मैं सोच रहा था कि एक सूची लौटने की बजाय, एक सूचक को लौटने की बजाय, प्रदर्शन की अवधि में महंगा था क्योंकि अगर मुझे याद है, तो सूची में बहुत से गुण नहीं हैं (क्या यह 3 पॉइंटर्स की तरह नहीं है? एक वर्तमान स्थिति के लिए, शुरुआत के लिए एक और अंत के लिए एक?)।एक std :: सूची महंगा लौट रहा है?
उत्तर
यदि आप मूल्य के अनुसार std::list
वापस लौटते हैं तो यह केवल सूची के शीर्ष की प्रतिलिपि नहीं करेगा, यह सूची में प्रति आइटम एक आइटम नोड कॉपी करेगा। तो हाँ, एक बड़ी सूची के लिए यह महंगा है।
यदि सूची उस फ़ंक्शन में बनाई गई है जो इसे वापस कर रही है, तो आप एक अनावश्यक प्रतिलिपि से बचने के लिए नामित वापसी मूल्य अनुकूलन से लाभ प्राप्त कर सकते हैं। यह आपके कंपाइलर के लिए विशिष्ट है, यद्यपि। यह तब लागू नहीं होता है जब उदाहरण के लिए फ़ंक्शन को कॉल करने से पहले सूची पहले से मौजूद हो (उदाहरण के लिए यदि यह किसी ऑब्जेक्ट का सदस्य चर है)।
मूल्य से कंटेनर लौटने से बचने के लिए सी ++ में एक सामान्य मुहावरे, आउटपुट इटरेटर को पैरामीटर के रूप में लेना है। तो बजाय:
std::list<int> getListOfInts() {
std::list<int> l;
for (int i = 0; i < 10; ++i) {
l.push_back(i);
}
return l;
}
आप कार्य करें:
template<typename OutputIterator>
void getInts(OutputIterator out) {
for (int i = 0; i < 10; ++i) {
*(out++) = i;
}
}
तो फोन करने वाले से करता है:
std::list<int> l;
getInts(std::back_inserter(l));
अक्सर एक बार संकलक इनलाइनिंग और अनुकूलन समाप्त हो गया है, कोड और अधिक या कम समान है ।
इसका लाभ यह है कि कॉलर किसी विशेष संग्रह से बंधे नहीं है - उदाहरण के लिए यदि वह विशेष परिस्थितियों के लिए अधिक उपयोगी होता है तो वह सूची के बजाय वेक्टर में आइटम जोड़ सकता है। यदि उन्हें केवल एक ही आइटम को एक साथ देखने की आवश्यकता है, तो उनमें से सभी के बजाय, फिर वह अपने स्वयं के चित्रण के आउटपुट इटरेटर का उपयोग करके स्ट्रीमिंग मोड में प्रोसेस करके स्मृति को सहेज सकता है।
नुकसान किसी भी टेम्पलेट कोड के समान हैं: कार्यान्वयन कॉलर को संकलन समय पर उपलब्ध होना चाहिए, और आप टेम्पलेट के कई तत्कालताओं के लिए "डुप्लिकेट" ऑब्जेक्ट कोड के साथ समाप्त हो सकते हैं। निस्संदेह आप एक पैरामीटर के रूप में एक फ़ंक्शन पॉइंटर (प्लस एक उपयोगकर्ता डेटा पॉइंटर वांछित) ले कर टेम्पलेट्स का उपयोग किए बिना समान पैटर्न का उपयोग कर सकते हैं और प्रत्येक आइटम के साथ इसे एक बार कॉल कर सकते हैं, या एक शुद्ध वर्चुअल सदस्य के साथ एक इंटीविजिटर अमूर्त वर्ग को परिभाषित करके कार्य, और कॉलर होने का एक उदाहरण प्रदान करते हैं।
[संपादित करें: टी.ई.डी. एक टिप्पणी में बताता है कि टेम्पलेट का उपयोग किये बिना प्रतिलिपि से बचने का दूसरा तरीका कॉलर के संदर्भ में एक सूची में पास होना है। यह निश्चित रूप से काम करता है, यह सिर्फ कॉलर को टेम्पलेट की तुलना में कम लचीलापन देता है, और इसलिए एसटीएल द्वारा उपयोग किया जाने वाला मुहावरे नहीं है। यदि आप उपरोक्त वर्णित "इसका लाभ" नहीं चाहते हैं तो यह एक अच्छा विकल्प है। हालांकि, एसटीएल के पीछे मूल इरादे में से एक "एल्गोरिदम" को अलग करना है (इस मामले में जो भी मान निर्धारित करता है) "कंटेनर" से (इस मामले में, तथ्य यह है कि मूल्यों को सूची में संग्रहीत किया जाना चाहिए, जैसा कि विरोध किया गया है एक वेक्टर या एक सरणी या एक स्व-सॉर्टिंग सेट के लिए, या बस उन्हें संग्रहीत किए बिना मुद्रित)।]
मेरा मानना है कि प्रति-निर्माता को बुलाया जाता है।
वास्तव में यह है, लेकिन मैं सोच रहा था कि कॉपी-कन्स्ट्रक्टर क्या कर रहा था। धन्यवाद अभी भी! –
मेरी सलाह: ब्रूस द्वारा सी ++ में सोचना खरीदें एकल, इस तरह के अधिकांश प्रश्न पहले पास के बाद चले जाएंगे ;-) – MadH
एंड्रयू कोएनिग और बारबरा मू द्वारा त्वरित सी ++ खरीदें। –
यह महंगा हो सकता है, जिसमें यह सूची में प्रत्येक तत्व की प्रतिलिपि बनायेगा। सबसे महत्वपूर्ण बात यह है कि इसमें अलग-अलग व्यवहार हैं: क्या आप सूची की एक प्रति चाहते हैं या आप मूल सूची में सूचक चाहते हैं?
यदि आप मूल्य से वापस आते हैं तो कॉपी कन्स्ट्रक्टर को बुलाया जाएगा और आइटम एक-एक करके कॉपी किए जाएंगे। कभी-कभी आपको नामित मूल्य अनुकूलन द्वारा सहेजा जाएगा क्योंकि एक व्यक्ति ने बताया है।
आपका मुख्य विकल्प प्रतिलिपि सुनिश्चित करने के लिए जगह नहीं ले जाएगा रहे हैं: संदर्भ द्वारा एक सूची में
- दर्रे में समारोह द्वारा भरा जाना है। इस तरह आप उस समारोह को बताते हैं जहां डेटा डालना है और कोई प्रतिलिपि बनाने की आवश्यकता नहीं है क्योंकि आप इसे अपने अंतिम स्थान पर डालते हैं।
- ढेर पर एक सूची आवंटित करें और इसे वापस करें। आपको इसे एक स्मार्ट पॉइंटर में std :: auto_ptr या boost :: shared_ptr जैसे इसे हटाने के लिए इसे हटा देना चाहिए और अपवाद सुरक्षित होना चाहिए।
यह (हमेशा के रूप में) निर्भर करता है। प्रतिलिपि कन्स्ट्रक्टर निम्नलिखित कोड में वापसी से लागू या नहीं किया जा सकता है।
std::list<int> foo() {
std::list<int> bar;
// ...
return bar;
};
यह लागू नहीं किया जा सकता है, तो संकलक return value optimization लागू होता है। यदि कॉपी-कन्स्ट्रक्टर कहा जाता है, तो यह बड़ी सूचियों के लिए सूचक के लिए शायद अधिक महंगी है, और यदि इसे नहीं कहा जाता है, तो सीधे सूची को वापस करने के लिए तेज़ है (क्योंकि यह गतिशील आवंटन से बचाता है)
व्यक्तिगत रूप से, मुझे इसके बारे में चिंता नहीं है और सीधे सूची लौटाएं। फिर, केवल जब मेरा प्रोफाइलर कहता है कि यह एक समस्या है, तो मैं अनुकूलन पर विचार करता हूं।
भी पढ़ा [यह] (http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/) – andreabedini
- 1. ElementTree findall() खाली सूची लौट रहा है
- 2. आंशिक एक महंगा ऑपरेशन बुला रहा है?
- 3. एक महंगा ऑपरेशन कास्टिंग कर रहा है?
- 4. CLGeocoder केवल एक प्लेसमार्क लौट रहा है
- 5. सर्विसस्टैक और एक स्ट्रीम लौट रहा है
- 6. एक प्रतिलिपि के बिना एक C++ std :: वेक्टर लौट रहा है?
- 7. एक अग्रेषित घोषित संरचना वापस अपरिभाषित व्यवहार लौट रहा है?
- 8. pthread_cond_timedwait तुरंत लौट रहा है
- 9. TextBlock.GetBindingExpression वापस लौट रहा है
- 10. Fetchall Python में केवल एक कॉलम लौट रहा है?
- 11. IJavaProject.findPackageFragmentRoots एक खाली सरणी क्यों लौट रहा है?
- 12. std :: सूची
- 13. php फ़ंक्शन 0 लौट रहा है?
- 14. PackageManager.getAplicationIcon() डिफ़ॉल्ट आइकन लौट रहा है?
- 15. CGContextClipToMask खाली छवि लौट रहा है
- 16. $ _FILES ["फ़ाइल"] ["आकार"] 0 लौट रहा है?
- 17. सी में va_list सुरक्षित लौट रहा है?
- 18. django.utils.timezone बेवकूफ तारीख लौट रहा है?
- 19. MySQL LOAD_FILE वापस लौट रहा है
- 20. ग्रोवी नोड.depthFirst() नोड्स और स्ट्रिंग्स की एक सूची लौट रहा है?
- 21. एंड्रॉइड: getSearchableInfo (getComponentName()) शून्य लौट रहा है?
- 22. सीएलएलोकेशन नकारात्मक गति लौट रहा है
- 23. ऑनप्रूवफ्रेम गलत बाइट लौट रहा है [] लंबाई
- 24. एंड्रॉइड जियोकोडर खाली पता लौट रहा है
- 25. फ़ाइल है। एक महंगा ऑपरेशन करता है?
- 26. आसानी से std :: तारों की एक std :: सूची शुरू करें?
- 27. क्या class.getName() महंगा है?
- 28. एक रिलेवेटलाइट लाइनरलायआउट से अधिक महंगा है?
- 29. अस्थिर महंगा है?
- 30. सी #: विधि घोंसले के लिए 'यह' लौट रहा है?
धन्यवाद, मैंने सोचा था कि यह केवल सिर की प्रतिलिपि बना रहा था! –
दिलचस्प। संदर्भ में सूची क्यों न दें? –
डर नहीं - किसी भी एसटीएल संग्रह की एक प्रति एक पूर्ण प्रति है (आइटम की प्रतियों सहित)। ऐसा इसलिए है कि जब आप प्रतिलिपि (या उसके तत्व) को संशोधित करते हैं तो आप मूल को भी संशोधित नहीं करते हैं। यहां तक कि यदि यह पॉइंटर्स का संग्रह है, तो पॉइंटर्स को अभी भी कॉपी करना होगा, हालांकि निश्चित रूप से ऑब्जेक्ट्स की प्रतिलिपि बनाई गई है, और संग्रह के बीच अभी भी "साझा" नहीं हैं। –