2010-07-22 7 views
14

मैं हमेशा सिखाया गया है कि गैर आदिम प्रकार स्थिरांक संदर्भ के बजाय मूल्य द्वारा पारित किया जाना चाहिए जहां संभव हो, अर्थात्:क्या छोटे सरल structs को संदर्भ संदर्भ से पारित किया जाना चाहिए?

void foo(std::string str);//bad 
void foo(const std::string &str);//good 

लेकिन मैं आज सोच रहा था कि शायद वास्तव में कुछ सरल उपयोगकर्ता परिभाषित प्रकार वास्तव में हो सकता है बेहतर मूल्य जैसे द्वारा पारित:

class Vector2 
{ 
public: 
    float x, y; 
    ...constructors, operators overloads, utility methods, etc... 
}; 

void foo(Vector2 pos); 
void foo(const Vector2 &pos);//is this really better than by value? 
void foo(float x, float y);//after all isn't by value effectively doing this? 

मेरे विचार आने लगे कि संदर्भ से Vector2 पास करके, यह संकलक के बाद से मूल्य से गुजर अब एक सूचक उपयोग कर रहा है और स्थिरांक Vector2 & स्थिति तक पहुँचने के लिए dereferencing से वास्तव में और अधिक महंगा है संस्करण?

क्या यह मामला है? क्या सरल वस्तुएं मूल्य से गुजरती हैं? रेखा को कहाँ खींचा जाना चाहिए?

+0

ध्यान दें कि यदि आपके क्लास-प्रकार में उपयोगकर्ता द्वारा घोषित कन्स्ट्रक्टर हैं, तो यह पीओडी नहीं है। –

+6

अंगूठे का सामान्य नियम: कॉन्स्ट-रेफरेंस द्वारा पास, जब तक कि 'आकार (टी) <= आकार (शून्य *) 'या' टी' आदिम नहीं है। – GManNickG

+2

@GMan, आपने मुझे इसे हराया (और +1)। हालांकि, मैं प्रोसेसर के शब्द-आकार से कम या उसके बराबर सामान्यीकृत करना चाहता हूं। और, इष्टतम आकार को खोजने के लिए प्रोसेसर चश्मे की जांच करनी चाहिए। अगर मुझे गलत नहीं लगता है, तो आकार के बावजूद, कंपाइलर्स कुछ मामलों में मूल्य से पास के पास एक कॉन्स रेफरी को संभावित रूप से अनुकूलित कर सकते हैं। मुझे लगता है कि यह विशेष रूप से सी ++ 0x में नया कदम अर्थशास्त्र दिया गया है। –

उत्तर

7

हां, साधारण वस्तुओं को मूल्य से पारित किया जाना चाहिए। रेखा वास्तुकला के अनुसार खींचा जाना है। अगर संदेह में, प्रोफ़ाइल।

+0

+1 प्रोफाइलिंग के लिए - यह बताने का एकमात्र तरीका है कि कौन सा बेहतर है –

1

कॉन्स्ट संदर्भ द्वारा उत्तीर्ण करने से एक नई वस्तु के निर्माण से बचा जाता है। यदि आपका कन्स्ट्रक्टर गैर-तुच्छ है, उदाहरण के लिए, यह स्मृति आवंटित करता है, तो आप अधिक मूल्य के मुकाबले कॉन्स्ट संदर्भ द्वारा पारित होने से बेहतर होगा।

सी # दुनिया में, आप यह निर्णय चुनकर यह निर्णय लेते हैं कि कुछ कक्षा या संरचना बनाना है या नहीं। कक्षाएं संदर्भ अर्थशास्त्र का उपयोग करती हैं जबकि structs मूल्य semantics का उपयोग करते हैं। जो कुछ भी मैंने कभी पढ़ा है, वह कहता है कि आपको आम तौर पर सब कुछ कक्षा बनाना चुनना चाहिए जब तक कि यह बहुत छोटा न हो, यानी, 16 बाइट्स के क्रम में। यदि आप सी ++ में मूल्य बनाम कॉन्स्ट संदर्भ द्वारा पारित होने के लिए कट ऑफ की तलाश में हैं, तो 16 बाइट उचित थ्रेसहोल्ड की तरह दिखते हैं।

+1

पीओडी प्रकारों में गैर-तुच्छ प्रतिलिपि बनाने वाले निर्माता नहीं हैं (या वास्तव में गैर-तुच्छ डिफ़ॉल्ट डिज़ाइनर या विनाशक)। –

+2

ओपी ने स्पष्ट रूप से पीओडी प्रकार नहीं कहा था। उन्होंने कहा ** सरल ** उपयोगकर्ता परिभाषित प्रकार और फिर एक उदाहरण दिया जो इंगित करता है कि इसमें एक निर्माता था। –

0

मेरे विचार आने लगे कि संदर्भ से Vector2 पास करके, यह संकलक के बाद से मूल्य से गुजर अब एक सूचक उपयोग कर रहा है और स्थिरांक Vector2 & स्थिति संस्करण

तक पहुँचने के लिए dereferencing से वास्तव में और अधिक महंगा है यह सच होगा यदि आपने ऑब्जेक्ट पास किया है जहां size_of(object) < size_of(pointer_to_object) है। उदाहरण के लिए, char const&char

+2

यह भी सच हो सकता है कि दोहराए गए डीरफ्रेंसिंग के परिणामस्वरूप अधिक डेटा गुजरने से बचाए जाने से अधिक ओवरहेड होगा। या यदि संदर्भ एलियासिंग चिंताओं के कारण अनुकूलन को रोकता है। या यदि संदर्भ आपके इलाके को नुकसान पहुंचाता है। –

1

नीति के मामले के रूप में, मैं किसी भी वस्तु को पास करता हूं जो मूलभूत डेटा डेटा प्रकार कॉन्स्ट संदर्भ द्वारा नहीं है। उस तरह याद रखना बहुत आसान है।

1

गुजरने वाले पैरामीटर के इंस-एन-आउट का एक पुराना, अभी तक स्पष्ट, विश्लेषण http://www.ddj.com/184403855 पर पाया जा सकता है। बेशक सी ++ 0x चलने वाले अर्थशास्त्र के साथ इस तरह के कई मुद्दों को रोकता है, लेकिन पेपर अर्थशास्त्र के वांछित क्यों हैं, इसके लिए पेपर बहुत औचित्य प्रदान करता है।

1

एक कारक जिसे मैंने नहीं देखा है वह है कि पारित मूल्य के साथ नियमित रूप से क्या किया जा रहा है। जब तक कि नियमित रूप से इनलाइन का विस्तार नहीं किया जाता है, संदर्भ द्वारा पारित किए गए डेटा में हेरफेर करने के लिए मूल्य से गुजरने वाले डेटा में हेरफेर करने से अधिक कोड की आवश्यकता होगी। यदि पारित संरचना के क्षेत्र औसतन एक बार से कम तक पहुंच जाएंगे, तो यह अतिरिक्त ओवरहेड संरचना की प्रतिलिपि बनाने के ऊपरी हिस्से की तुलना में छोटा होगा। यदि उन्हें औसतन कई बार एक्सेस किया जाएगा, तो संभवतः उन्हें ढेर पर रखना बेहतर होगा। यदि इंटरफेस पहले से ही एक संरचना के लिए पास-बाय-रेफरेंस के रूप में सेट किया गया है जिसे अत्यधिक एक्सेस किया जाता है, तो यह ब्याज के सभी हिस्सों की प्रतिलिपि बनाने के लिए बुलाए जाने वाले दिनचर्या के लिए समझ में आता है। दूसरी तरफ, यदि बुलाया गया दिनचर्या किसी भी या सभी संरचनाओं की प्रतिलिपि बनाने जा रहा है, तो यह भी मूल्य से पारित किया जा सकता है।

संबंधित मुद्दे