2014-10-27 15 views
9

में कुशल तरीका मेरे पास फ़ंक्शन से खाली स्ट्रिंग लौटने के 2 तरीके हैं।एक खाली स्ट्रिंग लौट रहा है: सी ++

1)

std::string get_string() 
{ 
    return ""; 
} 

2)

std::string get_string() 
{ 
    return std::string(); 
} 

जो एक है और अधिक कुशल और क्यों?

+12

न तो। 'वापसी {};' का प्रयोग करें। –

+2

और यह सी से कैसे संबंधित है? – crashmstr

+3

यह बेकार माइक्रो-ऑप्टिमाइज़ेशन के दायरे में पड़ता है कि आपका कंपाइलर आरवीओ का उपयोग करके ऑप्टिमाइज़ करेगा और एलिशन कॉपी करेगा। – CoryKramer

उत्तर

19

कुछ खुदाई हुई।

कोड::

#include <string> 

std::string get_string1(){ return ""; } 

std::string get_string2(){ return std::string(); } 

std::string get_string3(){ return {}; }   //thanks Kerrek SB 

int main() 
{ 
    get_string1(); 
    get_string2(); 
    get_string3(); 
} 

विधानसभा:

__Z11get_string1v: 
LFB737: 
    .cfi_startproc 
    pushl %ebx 
    .cfi_def_cfa_offset 8 
    .cfi_offset 3, -8 
    subl $40, %esp 
    .cfi_def_cfa_offset 48 
    movl 48(%esp), %ebx 
    leal 31(%esp), %eax 
    movl %eax, 8(%esp) 
    movl $LC0, 4(%esp) 
    movl %ebx, (%esp) 
    call __ZNSsC1EPKcRKSaIcE 
    addl $40, %esp 
    .cfi_def_cfa_offset 8 
    movl %ebx, %eax 
    popl %ebx 
    .cfi_restore 3 
    .cfi_def_cfa_offset 4 
    ret $4 
    .cfi_endproc 

__Z11get_string2v: 
LFB738: 
    .cfi_startproc 
    movl 4(%esp), %eax 
    movl $__ZNSs4_Rep20_S_empty_rep_storageE+12, (%eax) 
    ret $4 
    .cfi_endproc 

__Z11get_string3v: 
LFB739: 
    .cfi_startproc 
    movl 4(%esp), %eax 
    movl $__ZNSs4_Rep20_S_empty_rep_storageE+12, (%eax) 
    ret $4 
    .cfi_endproc 

यह -std=c++11 -O2 साथ संकलित किया गया था नीचे एक उदाहरण कार्यक्रम और प्रासंगिक विधानसभा है।

आप देख सकते हैं कि return ""; कथन के लिए बहुत अधिक काम है और return std::string और return {}; के लिए तुलनात्मक रूप से बहुत कम है (ये दोनों समान हैं)।

जैसे फ्रैरिक राबे ने कहा, खाली C_string खाली करते समय, इसे अभी भी स्मृति आवंटित करने के बजाय, इस पर प्रसंस्करण करने की आवश्यकता है।

return std::string(); 

या

return {}; //(c++11) 

हालांकि जब तक आप लौट रहे हैं: यह है कि इस दूर अनुकूलित नहीं किया जा सकता (कम से कम जीसीसी द्वारा नहीं)

तो जवाब निश्चित रूप से उपयोग करने के लिए है लगता है प्रदर्शन महत्वपूर्ण कोड (लॉगिंग मुझे लगता है?) में खाली तारों के बहुत सारे, अंतर अभी भी महत्वहीन नहीं होगा।

+0

हो सकता है कि इसे 2017 के रूप में अपडेट की आवश्यकता हो, तीनों संभावनाओं में से सभी रिटर्न उसी एएसएम परिणाम उत्पन्न करते हैं, इसलिए "" या std :: string {} या {} को वापस करने के बारे में कोई समस्या नहीं है। क्लैंग और जीसीसी –

+0

@ टोमाज़ कानाब्रावा के लिए कंपाइलर एक्सप्लोरर पर परीक्षण किया गया था, उस समय मुझे जीसीसी संस्करण का उल्लेख होना चाहिए ... यदि आप परीक्षण किए गए क्लैंग और जीसीसी संस्करणों को प्रदान करना चाहते हैं, तो मैं इसे उत्तर में नोट करूंगा। – Baldrickk

+0

@ टोमाज़ कानाब्रावा वास्तव में, जब मैं उपरोक्त के साथ जीसीसी और क्लैंग का प्रयास करता हूं, तो मुझे समान परिणाम मिलते हैं (जीसीसी 7.1/क्लैंग 4.0.0)। दिलचस्प रूप से पर्याप्त, विजुअल स्टूडियो (2015) परिणाम प्रदान करता है जो प्रत्येक संस्करण के बीच संगत होते हैं, लेकिन सभी मामलों में अधिक काम करते हैं। – Baldrickk

3

बाद वाला संस्करण पहले की तुलना में धीमा नहीं है। पहला संस्करण std::string कन्स्ट्रक्टर को एक सी स्ट्रिंग लेता है, जिसे पहले स्ट्रिंग की लंबाई की गणना करना होता है। भले ही यह एक खाली स्ट्रिंग के लिए तेज़ है, यह निश्चित रूप से ऐसा करने से तेज़ नहीं है।

+0

देखें क्योंकि यह एक निरंतर है जिसे वापस किया जा रहा है, क्या लंबाई गणना संकलक द्वारा अनुकूलित नहीं है? यदि नहीं, तो यह हो सकता है? – Baldrickk

+0

@ बाल्ड्रिक वह 'std :: string' के एक तर्क निर्माता को बुला रहा है।मुझे नहीं लगता कि बहुत से (यदि कोई हैं) कंपाइलर्स हैं जो यह समझने के लिए पर्याप्त चालाक हैं कि एक तर्क कन्स्ट्रक्टर कन्स्ट्रक्टर के बराबर होता है जो एक सूचक और आकार दोनों लेता है, बशर्ते यह स्ट्रिंग के आकार से कम हो शाब्दिक (जिसमें पिछला '' 0'' है)। –

+0

@JamesKanze: कुछ कंपाइलर स्ट्रिंग अक्षर पर 'strlen()' को अनुकूलित करते हैं - मैंने अनुरोध किया है कि एक दशक पहले स्पार्कवर्क्स सी ++ में सुविधा को जोड़ा जाए - यह नहीं पता कि उन्होंने कभी ऐसा किया है - जीसीसी ने पहले ही इसे वापस किया है। फिर भी - मैं जरूरी नहीं कि एक सी ++ कार्यान्वयन 'स्ट्रेलन' का उपयोग करने के लिए कार्यान्वित करता हूं ... हालांकि कभी नहीं पता। –

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