सामान्य मामले में (यहां सटीक होना कठिन है), ग्लोबल्स को स्मृति से पुनर्प्राप्त किया जाता है लेकिन स्टैक से नहीं (जब तक कि पहले से ही एक रजिस्टर में कैश नहीं किया जाता है), लूप को उस जानकारी के आधार पर अनुकूलित किया जा सकता है जो संकलक के पास है लूप करता है (क्या यह लूप अनोलिंग कर सकता है?) और तीसरे मामले में यह वास्तविक कोड पर निर्भर करता है।चूंकि पहले दो को पहले से ही अन्य प्रश्नों में निपटाया गया है, इसलिए मैं तीसरे प्रश्न पर ध्यान केंद्रित करूंगा।
एक सामान्य अनुकूलन (नामित) रिटर्न वैल्यू ऑप्टिमाइज़ेशन (एन) आरवीओ कहा जाता है कि संकलक अनावश्यक प्रतियों से बचने के लिए प्रदर्शन कर सकता है।
// RVO // NRVO // cannot perform RVO
type foo() { type bar() { type baz() {
value a; type a; type a,b;
// operate on a // modify a // pass a and b to other functions
return type(a); return a; if (random() > x) return a;
} } else return b;
}
दोनों foo
और bar
में, संकलक कोड का विश्लेषण और पाते हैं कि वह foo
में अस्थायी type(a)
या नामित स्थानीय चर a
bar
में हैं समारोह की वापसी मान करने में सक्षम है, तो यह कर सकते हैं वापसी वस्तुओं (कॉलिंग सम्मेलन के अनुसार) के स्थान पर उन वस्तुओं का निर्माण करें और इसे कॉपी करने से बचें। तुलना करें कि baz
के साथ जहां संकलक को वास्तव में यह जानना चाहिए कि कौन से को वापस लौटाया जाना है, पहले संकलक a
और b
बनाना चाहिए। इस मामले में संकलक कुछ भी अनुकूलित नहीं कर सकता है, ऑपरेशन करने के लिए और अंत में प्रति या तो a
या b
वापसी मूल्य पर प्रतिलिपि करना है।
जब भी कंपाइलर (एन) आरवीओ निष्पादित करता है या यदि यह वास्तव में निष्पादित करना असंभव है, संदर्भ द्वारा ऑब्जेक्ट प्राप्त करने के लिए फ़ंक्शन हस्ताक्षर को बदलना प्रदर्शन लाभ प्रदान नहीं करेगा और कॉल के स्थान पर कोड को कम पढ़ने योग्य कार्यों के लिए कोड देगा कि नई वस्तुओं बनाएँ।
यह अंगूठे के सामान्य नियम के रूप में उपयोग किया जाना चाहिए, लेकिन यह हमेशा के रूप में, अपवाद हैं, और ऐसे मामले जहां एक या दूसरे थोड़ा बेहतर प्रदर्शन कर सकते हैं। लेकिन ज्यादातर मामलों के लिए, और प्रदर्शन को मापने तक अन्यथा साबित नहीं होता है, आपको जितना संभव हो सके डिज़ाइन अर्थशास्त्र के करीब कोड लिखना चाहिए। यदि कोई फ़ंक्शन एक नई ऑब्जेक्ट बनाता है, तो उसे मान द्वारा वापस करें, यदि कोई फ़ंक्शन किसी ऑब्जेक्ट को संशोधित करता है, तो संदर्भ से गुजरता है।
कुछ विशेष मामले एक ऐसा कार्य हो सकते हैं जो वैक्टर बनाता है और उसे एक तंग लूप में बुलाया जाता है, जहां संदर्भ में पारित एक एकल वेक्टर होता है, जो फ़ंक्शन में साफ़ हो जाता है और फिर भरने से स्मृति आवंटन की संख्या कम हो जाती है (clear()
एक वेक्टर स्मृति को निष्क्रिय नहीं करता है, इसलिए इसे अगले पुनरावृत्ति में पुन: आवंटित करने की आवश्यकता नहीं है)।
दूसरी तरफ, जब फ़ंक्शन कॉल की जंजीर होती है, और रिटर्न बे मान के उचित संयोजन के साथ और मूल्य से गुजरती है, तो आप गैर-कॉन्स्ट संदर्भ में संदर्भों को पारित करके अतिरिक्त प्रतियों से बच सकते हैं, अस्थायी वस्तु।
(1) न तो, (2) वे नहीं हैं, (3) एनआरवीओ की वजह से यह नहीं होना चाहिए। –
आप बिंदु 3 में क्या मतलब है? संदर्भ द्वारा कार्य करने के लिए तर्कों को पास करना, या फ़ंक्शन तर्कों में से किसी एक द्वारा फ़ंक्शन मान वापस करना। –
@ पावेल: आरवीओ का अर्थ रिटर्न वैल्यू ऑप्टिमाइज़ेशन है, जिसका मतलब है कि एक प्रतिलिपि की लागत के बजाय मूल्य (जहां इसे वापस किया जाता है) का निर्माण करना है। जब यह अनुकूलन बढ़ता है, तो मूल्य से लौटने पर संदर्भ या सूचक को पारित करने से अधिक लागत नहीं होती है। –