c++ - स्ट्रिंग+= s1 और स्ट्रिंग=स्ट्रिंग+s1[बंद] के बीच अंतर




performance stdstring (3)

मौलिक प्रकारों के लिए, a = a + b और a += b अर्थ समान है।

मनमाना वर्ग प्रकारों के लिए, a = a + b और a += b असंबंधित हैं; वे विभिन्न ऑपरेटरों को देखते हैं, और वे ऑपरेटर मनमानी चीजें कर सकते हैं। उन्हें वास्तव में असंबंधित किया जा रहा है कोड गंध, एक डिजाइन समस्या का संकेत है।

a = a + b operator=( a, operator+( a, b ) ) बन जाता operator=( a, operator+( a, b ) ) मोटे तौर पर; वास्तविक लुकअप नियम थोड़े अधिक जटिल हैं (सदस्य ऑपरेटर और गैर-सदस्य ऑपरेटर शामिल हैं, और यह तथ्य कि = में एक गैर-सदस्य ऑपरेटर नहीं है, आदि), लेकिन यह इसका मूल है।

a += b एक ही अर्थ में operator+=( a, b ) बन जाता है।

अब, यह += संदर्भ में += लागू करने के लिए एक सामान्य पैटर्न है; यदि आप ऐसा करते हैं, तो आप प्राप्त करते हैं:

 a = a + b 

हो जाता है

 a = ((auto)(a) += b); 

जहां (auto) नया c ++ 20 / c ++ 23 है "तर्क की एक अस्थायी प्रतिलिपि बनाएँ" सुविधा।

मौलिक रूप से, a+=b सीधे की सामग्री का पुन: उपयोग कर सकता है, जबकि a = a + b नहीं कर सकता; फिलहाल a+b का मूल्यांकन किया गया है, यह नहीं पता है कि जल्द ही एक अधिलेखित कर दिया जाएगा।

कुछ लाइब्रेरी "एक्सप्रेशन टेम्प्लेट" नामक तकनीक का उपयोग करके इससे निपटते हैं; a+b एक मान नहीं है, बल्कि अभिव्यक्ति a+b एक संकलन-समय वर्णन है, जो जब a को सौंपा जाता a तो वास्तव में डेटा के साथ पॉप्युलेट करने के लिए उपयोग किया जाता है। एक्सप्रेशन टेम्प्लेट के साथ, a=a+b से अधिक जानने का a+=b का मूल मुद्दा समाप्त हो जाता है।

अब, std::string लिए, विशेष रूप से, a+b एक अस्थायी स्ट्रिंग ऑब्जेक्ट बनाता है, फिर a=(a+b) चलता है, जिसमें a (यह अस्थायी स्ट्रिंग ऑब्जेक्ट के बफर या a के बफर का पुन: उपयोग कर सकता a , मानक है) इस मामले पर चुप)।

a+=b को बफर में किसी भी अतिरिक्त क्षमता का पुन: उपयोग करना चाहिए। इसलिए यदि आप a.reserve(1<<30) (1 बिलियन), a+=b अधिक आवंटित नहीं कर सकते हैं।

मेरा एक कार्यक्रम उस समय सीमा को पार कर रहा है जब मैं fans = fans + s[i] का उपयोग कर रहा हूं fans = fans + s[i] , जबकि जब मैं fans += s[i] का उपयोग कर रहा हूं fans += s[i] यह स्वीकार किया जा रहा है ... ऐसा क्यों होता है? अधिक स्पष्ट करने के लिए, प्रशंसक एक स्ट्रिंग है और एस भी एक स्ट्रिंग है, इसलिए स्ट्रिंग पर पुनरावृति करते हुए, सी केवल कुछ वर्ण चाहते हैं इसलिए मैं एक नया स्ट्रिंग प्रशंसक बना रहा हूं। अब दो तरीके हैं जिसमें मैं अपने नए स्ट्रिंग में चरित्र जोड़ सकता हूं प्रशंसकों। समस्या का उल्लेख नीचे किया गया है

fans = fans + s[i]; // gives Time limit exceeded 
fans += s[i];       // runs successfully

यदि आप fans=fans+s[i] उपयोग fans=fans+s[i] , स्ट्रिंग को हर लूप पास में कॉपी किया जाएगा। नया तत्व स्ट्रिंग की प्रतिलिपि में जोड़ा जाएगा और परिणाम चर fans को फिर से सौंपा जाएगा। इसके बाद पुराने तार को हटाना होगा क्योंकि यह अब संदर्भित नहीं है। इसमें पूरा समय लगता है।

यदि आप संवर्धित असाइनमेंट fans+=s[i] उपयोग करते हैं fans+=s[i] स्ट्रिंग को प्रत्येक लूप पास में कॉपी नहीं किया जाएगा और संदर्भ चर को हटाने की कोई आवश्यकता नहीं है क्योंकि यहां कोई संदर्भ चर नहीं है। इससे काफी समय की बचत होती है।

मुझे उम्मीद है कि अब आप समझ सकते हैं !!


बिल्ट-इन प्रकारों के लिए a += b बिल्कुल a = a + b , लेकिन कक्षाओं के लिए, उन ऑपरेटरों को ओवरलोड किया जाता है और विभिन्न कार्यों को कॉल किया जाता है।
आपके उदाहरण में fans = fans + s[i] एक अस्थायी स्ट्रिंग बनाता है, और इसे fans को भेजता है (स्थानांतरित करता है), लेकिन fans += s[i] यह अस्थायी नहीं बनाता है, इसलिए यह तेज़ हो सकता है।





compound-assignment