मैं वाक्य से असहमत हूं "मुझे लगता है कि आपके कोड को कुशलता से चलाने के लिए संकलक अनुकूलन पर भरोसा करना सबसे अच्छा नहीं है।" यह मूल रूप से संकलक का पूरा काम है। आपका काम स्पष्ट, सही और रखरखाव स्रोत कोड लिखना है। मुझे कभी भी ठीक करने के लिए हर प्रदर्शन मुद्दे के लिए, मुझे कुछ सरल, सही और रखरखाव करने की बजाए चतुर होने की कोशिश करने वाले डेवलपर द्वारा किए गए सौ या अधिक मुद्दों को ठीक करना पड़ा।
चलिए कुछ चीजों को देखें जो आप कंपाइलर को "मदद" करने की कोशिश करने के लिए कर सकते हैं और देखें कि वे स्रोत कोड की रखरखाव को कैसे प्रभावित करते हैं।
के माध्यम से डेटा वापस कर सकता है उदाहरण के लिए:
void hello(std::string& outString)
रिटर्निंग एक संदर्भ का उपयोग कर डेटा कॉल-साइट को पढ़ने के लिए मुश्किल में कोड बनाता है।यह कहना लगभग असंभव है कि कौन सा फ़ंक्शन एक साइड इफेक्ट के रूप में राज्य को म्यूटेट करता है और जो नहीं करता है। भले ही आप संदर्भों को अर्हता प्राप्त करने के साथ वास्तव में सावधान रहें, कॉल साइट पर पढ़ना मुश्किल होगा। निम्नलिखित उदाहरण पर विचार करें:
void hello(std::string& outString); //<-This one could modify outString
void out(const std::string& toWrite); //<-This one definitely doesn't.
. . .
std::string myString;
hello(myString); //<-This one maybe mutates myString - hard to tell.
out(myString); //<-This one certainly doesn't, but it looks identical to the one above
यहां तक कि हैलो की घोषणा स्पष्ट नहीं है। क्या यह बाहर स्ट्रिंग को संशोधित करता है, या लेखक सिर्फ मैला था और संदर्भ को अर्हता प्राप्त करने के लिए भूल गया था? functional style में लिखा गया कोड पढ़ने और समझना और गलती से तोड़ना कठिन है।
बचें
- आप के बजाय वस्तु के लिए एक सूचक लौट सकते हैं वस्तु लौटने का।
ऑब्जेक्ट पर पॉइंटर लौटने से यह सुनिश्चित करना मुश्किल हो जाता है कि आपका कोड भी सही है। जब तक आप एक unique_ptr का उपयोग नहीं करते हैं, आपको विश्वास करना होगा कि आपकी विधि का उपयोग करने वाले किसी भी व्यक्ति को पूरी तरह से पूरा किया जाता है और जब वे इसके साथ होते हैं तो पॉइंटर को हटाना सुनिश्चित करता है, लेकिन यह RAII नहीं है। std :: स्ट्रिंग पहले से ही एक char * के लिए RAII wrapper का एक प्रकार है जो एक पॉइंटर लौटने से जुड़े डेटा आजीवन मुद्दों को दूर करता है। एक std :: स्ट्रिंग में पॉइंटर लौटने से केवल उन समस्याओं को फिर से पेश किया जाता है जो std :: string को हल करने के लिए डिज़ाइन किया गया था। एक इंसान पर निर्भर होना और सावधानी से अपने फ़ंक्शन के लिए प्रलेखन को पढ़ना और पता होना चाहिए कि पॉइंटर को कब हटाना है और जब पॉइंटर को हटाना नहीं है तो सकारात्मक परिणाम होने की संभावना नहीं है।
बचें
- कंस्ट्रक्टर्स स्थानांतरित करने के लिए हमें लाता है।
एक चालक कन्स्ट्रक्टर केवल 'परिणाम' से अपने अंतिम गंतव्य तक बिंदु से डेटा के स्वामित्व को स्थानांतरित कर देगा। इसके बाद, 'परिणाम' ऑब्जेक्ट तक पहुंच अमान्य है लेकिन इससे कोई फर्क नहीं पड़ता - आपकी विधि समाप्त हो गई और 'परिणाम' ऑब्जेक्ट दायरे से बाहर हो गया। कोई प्रतिलिपि नहीं, स्पष्ट अर्थशास्त्र के साथ सूचक के स्वामित्व का हस्तांतरण।
आम तौर पर संकलक आपके लिए चालक कन्स्ट्रक्टर को कॉल करेगा। यदि आप वास्तव में पागल हैं (या विशिष्ट ज्ञान है कि संकलक आपकी मदद नहीं करेगा) तो आप std::move का उपयोग कर सकते हैं।
यदि सभी संभव
पर अंत में आधुनिक compilers अद्भुत हैं इस एक कार्य करें। एक आधुनिक सी ++ कंपाइलर के साथ, 99% समय संकलक कॉपी को खत्म करने के लिए कुछ प्रकार के अनुकूलन करने जा रहा है। अन्य 1% समय शायद यह प्रदर्शन के लिए कोई फर्क नहीं पड़ता है। विशिष्ट परिस्थितियों में संकलक std :: स्ट्रिंग GetString() जैसी विधि को फिर से लिख सकता है; GetString शून्य करने के लिए (std :: string & outVar); खुद ब खुद। कोड अभी भी पढ़ने में आसान है, लेकिन अंतिम असेंबली में आपको संदर्भ द्वारा लौटने के सभी वास्तविक या कल्पना गति लाभ मिलते हैं। प्रदर्शन के लिए पठनीयता और रखरखाव का त्याग न करें जब तक कि आपके पास विशिष्ट ज्ञान न हो कि समाधान आपकी व्यावसायिक आवश्यकताओं को पूरा नहीं करता है।
ऑप्टिमाइज़ न करें जब तक कि आपने पुष्टि नहीं की है कि आपका समाधान व्यावसायिक आवश्यकताओं को पूरा नहीं करता है और फिर केवल यह अनुकूलित करता है कि प्रोफाइलर आपको क्या धीमा कर रहा है। कंपाइलर इसे संभालने दें। इसे पढ़ना और बनाए रखना आसान होगा। –
सी ++ में यह लगभग निश्चित रूप से एक चालक कन्स्ट्रक्टर का उपयोग करेगा यदि किसी कारण से आरवीओ विफल रहता है। यदि आप पूरी तरह से सुनिश्चित होना चाहते हैं, तो आउटपुट स्ट्रिंग को संदर्भित करने के बजाय संदर्भ में पास करें। आरवीओ अब मानक का हिस्सा है, हालांकि जब तक आपके पास आधुनिक कंपाइलर है, तो आप आम तौर पर इस पर भरोसा कर सकते हैं। –
@PeteBaughman और जोनाथन पॉटर: मुझे एहसास है कि संकलक इसे अनुकूलित कर सकता है, और इससे मेरे आवेदन में भारी ओवरहेड नहीं हो सकता है, लेकिन यह एक मूलभूत आवश्यकता को समझ में नहीं पा रहा है? –