2011-11-12 17 views
6

उदाहरण के लिए हमारे पास एन्कोडिंग फ़ंक्शन है। उपयोग करने के लिए सर्वोत्तम तरीका क्या है:संदर्भ या वापसी - सर्वोत्तम अभ्यास

void Crypto::encoding(string &input, string &output) 
{ 
    //encoding string 
    output = encoded_string; 
} 

या

string Crypto::encoding(string &input) 
{ 
    //encoding string 
    return encoded_string; 
} 

हम संदर्भ का उपयोग करना चाहिए या स्ट्रिंग लौटने के लिए वापसी? जहां तक ​​मुझे पता है कि एक स्ट्रिंग लौटने में एक नई स्ट्रिंग शुरू करने में कुछ समय लगेगा जो रिटर्न निर्देश द्वारा वापस किया जाएगा। एक संदर्भित चर पर काम करते समय मैं कुछ नए चर शुरू करने के लिए समय बर्बाद नहीं करता हूं, मैं बस कार्य को समाप्त करता हूं।

क्या हमें अधिकतर संदर्भ का उपयोग करना चाहिए और फ़ंक्शन रिटर्न प्रकार शून्य करना चाहिए? या हमें केवल संदर्भ द्वारा डेटा वापस करना चाहिए जब हम दो या दो से अधिक चर वापस करना चाहते हैं और जब हमें एक वैरिएबल लौटने की आवश्यकता होती है तो वापसी निर्देश का उपयोग करें?

+0

कोड प्रारूपित करने के लिए संपादक में '{} 'बटन का उपयोग करें। – Mat

+7

क्या आप * उन "समय" के बारे में चिंतित हैं जिनके बारे में आप बात करते हैं? क्या आपने प्रोफाइलिंग और दृढ़ संकल्प किया है कि स्ट्रिंग निर्माण का समय आपके आवेदन की बाधा है? –

उत्तर

1

नए मानक सी ++ 11 के साथ, आप नए चरण अर्थशास्त्र के कारण दूसरे संस्करण का उपयोग कर सकते हैं।

शायद, हालांकि, आपका कंपाइलर अभी भी पुराने मानक का समर्थन करता है। इस मामले में, आपका पहला उदाहरण किसी भी प्रतिलिपि को उत्तेजित नहीं करता है और बेहतर है।

+0

माइक्रो ऑप्टिमाइज़ेशन की तरह लगता है –

+1

@VJo: वास्तव में नहीं, अगर आपकी स्ट्रिंग में लाखों वर्ण हैं या यदि आप इस समारोह को लाख बार कहते हैं तो आपको केवल दूसरे उदाहरण की तुलना में पहले उदाहरण में स्मृति का आधा स्पर्श करना होगा। यही कारण है कि पहली जगह में अर्थशास्त्र को स्थानांतरित किया गया था। – Manuel

+4

दूसरा शायद कॉपीिंग का आह्वान नहीं करता है, आरवीओ/एनआरवीओ या http://stackoverflow.com/q/1394229/79455 – rve

6

चीजों की प्रतिलिपि आमतौर पर समाप्त हो जाती है क्योंकि अधिकांश आधुनिक कंपाइलरों में आरवीओ विशेषताएं होती हैं। आप सी ++ 11 के बिना भी लाभ ले सकते हैं।

9

जो आपने माप नहीं किया है उसे अनुकूलित न करें।

आमतौर पर यह return के साथ आपके गणना के परिणाम को वापस करने के लिए बेहतर (अधिक पठनीय) है। यदि यह बहुत लंबा होता है क्योंकि ऑब्जेक्ट बहुत मोटा होता है, तो आप अभी भी संदर्भ पैरामीटर के माध्यम से अपना परिणाम वापस करने के लिए वापस आ सकते हैं, लेकिन केवल यह साबित करने के बाद कि इसका प्रदर्शन प्रदर्शन में महत्वपूर्ण सुधार होगा (इसे मापें)। उदा। यदि आप केवल बहुत ही कम तारों को एन्कोड करते हैं और केवल थोड़ी देर में ऐसा करते हैं, तो कॉपी करने का ओवरहेड नगण्य है।

+2

+1 * जो आपने माप नहीं किया है उसे ऑप्टिमाइज़ न करें *, स्कॉट मेयर्स ऑप्टिमाइज़ेशन पर उद्धरण यहां उपयुक्त होगा "आपको अपने कोड का 20% पहचानने की आवश्यकता है जो 90% रन टाइम चलाता है और फिर कोशिश करें अपने कोड का 20% अनुकूलित करें। " सटीक शब्दों को याद न करें, लेकिन हां इच्छित अर्थ वही था। –

+0

मैंने सोचा था कि 10% था, 20% नहीं :-) – rve

+1

मापने की बात करते हुए, जी ++ 4.3 पर, दोनों कार्य समान गति से चलते हैं। http://ideone.com/sgl9W –

2

यदि आपका कंपाइलर सी ++ 11 मानक और r-value references का समर्थन करता है तो मूल्य द्वारा std :: स्ट्रिंग को वापस करना वास्तव में काफी कुशल है। इस सुविधा से पहले उत्तर थोड़ा अलग हो सकते थे क्योंकि आप केवल RVO प्रदर्शन करने वाले कंपाइलर पर निर्भर होंगे।

मैं कहूंगा कि रिटर्न वैल्यू का उपयोग करना शायद अधिक स्वाभाविक है और इसका मतलब यह भी है कि आप आकस्मिक संशोधन से बचने के लिए परिणाम को निरंतर स्थानीय चर या वर्ग सदस्य को असाइन कर सकते हैं।

const std::string result = crypo.encoding("blah"); 

या

class SomeClass 
{ 
public: 
    Someclass(Crypto& crypto, const std::string& input) : 
     m_output(crypo.encoding(input)) 
    { 
    } 

private: 
    const std::string m_output; 
}; 

बस सुनिश्चित करें कि आप के रूप में इस कदम अर्थ विज्ञान से रोक सकता है स्थिरांक मान द्वारा वापसी नहीं कर

1

मैं रिकॉर्ड के रूप में कहूंगा: शायद न तो एक।

आपका encode मुझे ऐसा लगता है कि यह एक सामान्य एल्गोरिदम हो सकता है जिसे वास्तव में स्ट्रिंग्स के साथ सीधे निपटने के बजाय इटरेटर का उपयोग करना चाहिए।

template <class InputIterator, class OutputIterator> 
void encode(InputIterator begin, InputIterator end, OutputIterator result) { 
    while (begin!=end) 
     *result++ = encode_byte(*begin++); 
} 

इस तरह आप (उदाहरण के लिए) आसानी से पुनः उपयोग कर सकते हैं (एक std::ostream_iterator के माध्यम से) एक निर्गम धारा के लिए एक इनपुट स्ट्रीम (एक std::istream_iterator के माध्यम से) से सीधे डेटा एन्कोड करने के लिए बिल्कुल एक ही कोड।

यह आमतौर पर दक्षता के बारे में अधिकतर प्रश्नों को समाप्त करता है।

+0

बस सोच रहा है: अगर मैं आपके काम में 'सैमिक :: इटरेटर' खिलाता हूं, तो 'एन्कोड_बीटे()' कैसे सैमिक को एन्कोड करने के बारे में जानता है? आपको वास्तव में जेनेरिक होने के लिए एन्कोडिंग एल्गोरिदम की आपूर्ति करने की भी आवश्यकता होगी, लेकिन जो आपके फ़ंक्शन से छोड़ा जाएगा वह पुनरावृत्ति है इसलिए इसे 'for_each'' नाम दिया जाना चाहिए ... ;-) – EricSchaefer

+0

@EricSchaefer: यह स्पष्ट रूप से नहीं है प्रत्येक संभावित इनपुट प्रकार को एन्कोड करने के तरीके के बारे में विशेष ज्ञान प्राप्त करें। हालांकि, यह डेटा (डेटा) धारक के प्रकार से स्वतंत्र हो सकता है। –

+0

निश्चित रूप से यह सिर्फ std :: ट्रांसफॉर्म है जिसका आप वर्णन कर रहे हैं? –

2

मैं संदर्भों का उपयोग करता हूं। यह कार्यान्वयनकर्ता को क्लाइंट को भारी कर लगाने के बिना पसंद को बनाने और अमूर्त करने की अनुमति देता है (कुछ मामलों में मामला, कुछ नहीं होगा)।

मैं उन्हें लगातार शैली के लिए भी उपयोग करता हूं - मुझे उनके कार्यान्वयन के विवरण द्वारा पारित सार्वजनिक इंटरफेस देखना पसंद नहीं है।

ट्रांजिस्टर और प्रतियां महंगी हो सकती हैं - यह आपके द्वारा गुजरने वाले प्रकार से काफी भिन्न होती है। मूल्य से वापस आने के लिए इंगित करता है कि प्रकार को छोटे पैमाने पर रचनात्मक, स्वीकार्य, प्रतिलिपि योग्य, चलाना चाहिए। कंपाइलर इस क्षेत्र (आरवीओ/चाल) में कुछ बेहतरीन अनुकूलन कर सकता है, लेकिन आप अपने कार्यान्वयन में महंगी परिचालन को कम करने के लिए सूचित निर्णय भी ले सकते हैं। एक बार जब आप अब प्रकारों का उपयोग नहीं कर रहे हैं, तो सभी प्रतिलिपि विशेषताओं को जानते हैं, फिर वापस लौटने का तरीका चुनना बहुत जटिल हो जाता है, इसलिए मैं इसे सरल और संदर्भों का समर्थन करता हूं।

किसी संदर्भ को पास करने से कुछ अन्य लाभ होते हैं, जैसे क्लाइंट पास किए गए प्रकार के उप-वर्ग का उपयोग करना पसंद करता है।

यदि आपको एक अनुकूलित प्रोग्राम की आवश्यकता है तो एक और लाभ: मैं अक्सर कॉपी सीटीओआर और operator= हटा दूंगा यदि वे छोटे या संभव नहीं हैं। उत्परिवर्तनीय संदर्भ द्वारा उत्तीर्ण करने से आप उन प्रकारों के साथ काम कर सकते हैं जो कॉपी/असाइन करने योग्य नहीं हैं।

std::string की सख्त गुंजाइश इस सवाल में प्रयोग किया जाता में: लौटने एक std::string मूल्य से काफी आम है, और कई अनुकूलन इस मामले के लिए विशेष रूप बनाया गया है - RVO, गाय, और चाल कुछ उल्लेखनीय हैं। चूंकि नीचे उल्लिखित टिप्पणियों में उल्लू ने उल्लेख किया है, मूल्य से लौटने के लिए अक्सर पढ़ने में आसान होता है। std::string और उच्च स्तर के कार्यक्रमों के मामले में, मूल्य से लौटने की कोई समस्या नहीं होने की संभावना है, लेकिन मानक लाइब्रेरी कार्यान्वयन के लिए शामिल लागतों को समझने के लिए मापना महत्वपूर्ण है यदि प्रदर्शन महत्वपूर्ण है (जो आपका प्रश्न सुझाता है मामला हो सकता है)।

एक महत्वपूर्ण विचार है कि यदि आप एक मौजूदा कार्यक्रम को बेहतर बनाने की कोशिश कर रहे, सुनिश्चित करें कि आप समझ कैसे कार्यान्वयन कार्यान्वित करता है, और जानें कि कैसे आप प्रकार सबसे अधिक प्रभावी ढंग से इस्तेमाल कर सकते हैं जब प्रदर्शन महत्वपूर्ण है है। कार्यान्वयन वास्तविक उपयोग के लिए अनुकूलित और अनुकूलित किया जा सकता है, जिसका अर्थ यह है कि वे निराशावादी हो सकते हैं और कुछ मामलों में आपको अनुमान लगाया जा सकता है, और प्रदर्शन में सुधार करने के आपके प्रयासों को पहले ही लागू किया जा सकता है या प्रदर्शन को अपनाने के लिए अपरंपरागत उपयोग हो सकता है। std::vector का विशिष्ट आकार बदलने का व्यवहार एक स्पष्ट उदाहरण है। उच्च प्रदर्शन सड़क लेना आपको सर्वोत्तम परिणामों को प्राप्त करने के लिए जो कुछ जानने की आवश्यकता है, उसके बारे में बहुत समय और जटिलता जोड़ता है, और यह स्पष्ट रूप से आपके द्वारा उपयोग किए जाने वाले कार्यान्वयन और आपके द्वारा उपयोग किए जा रहे प्रकारों के अनुसार भिन्न होता है। यदि प्रदर्शन महत्वपूर्ण और मूल्यवान समय के निवेश के लिए है, तो आपके द्वारा उपयोग किए जाने वाले प्रकारों के संचालन को सीखना एक सार्थक प्रयास है जो महत्वपूर्ण लाभ प्राप्त कर सकता है।

मैं भी जोड़ना चाहिए कि मैं अक्सर निम्न स्तर में काम करते हैं - जहां प्रदर्शन के लिए महत्वपूर्ण है और/या संसाधन सीमित हैं। कोई अपवाद नहीं, कई ताले (कोई ढेर आवंटन का तात्पर्य नहीं है), न्यूनतम अमूर्त लागत, और गतिशील बहुरूपता के प्रतिबंधित उपयोग सहित कई प्रतिबंध भी हो सकते हैं। इसे सी ++ के लिए भी काफी मांग करने वाला डोमेन माना जा सकता है। मैं कोर निम्न स्तर टुकड़े के लिए संदर्भ चुनते हैं, लेकिन मुझे लगता है कि शासन को आराम होगा अगर मैं जानता हूँ कि एक कार्यक्रम केवल उच्च स्तर डोमेन या इकाई परीक्षण में इस्तेमाल किया जाएगा।

+0

@anonymous_downvoter यह बहुत मदद नहीं करता है, जब तक कि आप अपनी कार्रवाई को उचित न दें। – justin

+1

जबकि मुझे सच में लगता है कि ऑब्जेक्ट को वापस करने से कोड पढ़ने के लिए सरल और आसान हो जाता है, तो आप निश्चित रूप से यहां एक उचित तर्क देते हैं, इसलिए +1 - कॉपी सीटीओआर और ऑपरेटर = से छुटकारा पाने में सक्षम होना वास्तव में अच्छा है और मुझे प्यार होगा ऐसा करने के लिए .. अच्छी तरह से कुछ भी सही नहीं है। – Voo

+0

@ वू हां, मैं मानता हूं कि मूल्य से लौटना अक्सर पढ़ने में आसान होता है (esp। जब टाइप सरल 'std :: string' के रूप में होता है)। मैं अब इस उत्तर में कुछ विवरण/पृष्ठभूमि जोड़ने जा रहा हूं कि मैंने इसे फिर से पढ़ा है। चीयर्स। – justin

1

मुझे दूसरा संस्करण बेहतर पसंद है, क्योंकि यह गणितीय फ़ंक्शन की तरह दिखता है। यदि आप केवल स्ट्रिंग लौट रहे हैं तो आपको अच्छा प्रदर्शन करना चाहिए।

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