2016-07-29 21 views
7

विपरीत std :: वेक्टर, std :: स्ट्रिंग एक एकल निर्माता है कि एक आकार लेता है प्रदान नहीं करता है:std :: string (आकार, ' 0') और s.resize (आकार) के बीच अंतर?

std::string s(size, '\0'); 

और

std::string s; 
s.resize(size); 
:

std::string s(size); // ERROR 

वहाँ के बीच कोई अंतर है सामान्य कार्यान्वयन पर उनके प्रदर्शन के संदर्भ में

?

स्ट्रिंग को सभी शून्य वर्णों में स्ट्रिंग प्रारंभ करने का आकार बदल देगा या क्या यह उन्हें एक अनिर्दिष्ट मान छोड़ देगा?

यदि सभी शून्य है, तो किसी दिए गए आकार की स्ट्रिंग बनाने का कोई तरीका है, लेकिन अक्षरों को अनिर्दिष्ट मान के साथ छोड़ दें?

+0

'आकार' क्या है, क्या यह आकार = 0' है? –

+1

@ फर्स्टस्टेप: नहीं, जहां 'आकार' कुछ 'size_t' है जो'> 0' है। –

+0

क्या आपने अपने प्रदर्शन को मापने के लिए एक प्रोफाइलर के माध्यम से कुछ कार्यान्वयन चलाए? –

उत्तर

4

std::string s(size, '\0'); में एक अंतर है, स्ट्रिंग के लिए आवश्यक सभी मेमोरी को एक साथ आवंटित किया जा सकता है। हालांकि, दूसरे उदाहरण के साथ, यदि size छोटे स्ट्रिंग ऑप्टिमाइज़ेशन के लिए संग्रहीत वर्णों की मात्रा से अधिक है, तो अतिरिक्त आवंटन करना पड़ सकता है, हालांकि यह कार्यान्वयन परिभाषित किया गया है, और मानक में उस संबंध में निश्चित रूप से अधिक प्रदर्शन नहीं करेगा -कंपीदार सी ++ 17 कार्यान्वयन। हालांकि, पहला उदाहरण अधिक consise है, और अधिक प्रदर्शनकारी हो सकता है, तो यह शायद बेहतर है। s.resize(size); पर कॉल करते समय, सभी नए पात्रों को char के डिफ़ॉल्ट कन्स्ट्रक्टर, उर्फ ​​'\0' के साथ प्रारंभ किया जाएगा। अनिर्दिष्ट मानों के साथ string आरंभ करने का कोई तरीका नहीं है।

+4

दूसरे मामले में दूसरा आवंटन क्यों होगा? दोनों मामलों में, यदि 'आकार' एसएसओ बफर से अधिक है, तो एक आवंटन होगा। – Praetorian

+0

इसी कारण से 'make_unique() 'तेज है तो एक' नया 'कॉल और कन्स्ट्रक्टर को कॉल करना। पहले मामले में, सभी मेमोरी 'std :: string' जरूरतों को एक साथ आवंटित किया जा सकता है। हालांकि, दूसरे मामले में, 'नए' को दो बार बुलाया जाना पड़ सकता है।हालांकि कार्यान्वयन परिभाषित किया गया है, जिसे मैं स्पष्ट करूंगा। – DeepCoder

+6

* इसी कारण से 'make_unique() 'तेज है तो एक' नया 'कॉल और कन्स्ट्रक्टर * को कॉल कर रहा है ... क्या आप' make_shared' के बारे में सोच रहे हैं, क्योंकि' make_unique' के साथ कोई अंतर नहीं होना चाहिए। वैसे भी, मैं देखता हूं कि आप डिफ़ॉल्ट रूप से 'std :: string' का निर्माण कर रहे हैं, स्मृति को आवंटित करेंगे, जो बहुत असामान्य होगा, लेकिन अनुमति होगी। लेकिन फिर भी, यह कहते हुए कि एक अंतर गलत लगता है। वहां * एक अंतर हो सकता है, लेकिन अधिकतर संभावना नहीं है, जब तक कि आप कुछ चर को '0' में प्रारंभ करने पर विचार न करें और फिर उन्हें बदल दें, बनाम उन्हें' आकार 'से शुरू करने के लिए प्रारंभ करें, एक अंतर। – Praetorian

4

वास्तविक उत्तर कार्यान्वयन-आधारित होगा, लेकिन मुझे पूरा यकीन है कि std::string s(size, '\0'); तेज है।

std::string s; 
s.resize(size); 

documentation for std::string के अनुसार।

1) डिफ़ॉल्ट कन्स्ट्रक्टर। खाली स्ट्रिंग (शून्य आकार और निर्दिष्ट क्षमता) का निर्माण करता है।

डिफ़ॉल्ट कन्स्ट्रक्टर "अनिर्दिष्ट क्षमता" के साथ एक स्ट्रिंग बनाएगा। मेरी समझ यह है कि कार्यान्वयन 10-15 वर्णों (पूरी तरह से अटकलें) के दायरे में, डिफ़ॉल्ट क्षमता निर्धारित करने के लिए स्वतंत्र है।

फिर अगली पंक्ति में, आप नए size के साथ स्मृति (resize) पुनः आवंटित करेगा अगर size वर्तमान capacity से अधिक है। यह शायद आप नहीं चाहते हैं!

यदि आप वास्तव में निश्चित रूप से जानना चाहते हैं, तो आप दो विधियों पर एक प्रोफाइलर चला सकते हैं।

2

DeepCoder से पहले से ही एक अच्छा जवाब है।

रिकॉर्ड तथापि के लिए, मुझे लगता है कि (जैसा कि वैक्टर के लिए) तार वहाँ दो अलग-अलग विचार हैं का कहना चाहते हैं:

  • size(): यह वास्तविक (यानी सार्थक) में वर्णों की संख्या है स्ट्रिंग।आप इसे resize() का उपयोग करके बदल सकते हैं (जिसमें आप यह कहने के लिए दूसरा पैरामीटर प्रदान कर सकते हैं कि आप किस प्रकार के रूप में उपयोग करना चाहते हैं '\0')
  • capacity(): यह स्ट्रिंग को आवंटित वर्णों की संख्या है। इसका कम से कम आकार लेकिन अधिक हो सकता है। आप इसे reserve()

यदि आप आवंटन प्रदर्शन के बारे में चिंतित हैं, तो मुझे विश्वास है कि क्षमता के साथ खेलना बेहतर है। पैडिंग वर्णों के लिए स्ट्रिंग में असली वर्णों के लिए आकार को वास्तव में रखा जाना चाहिए।

वैसे, अधिक सामान्यतः s.resize(n)s.resize(n, char()) जैसा ही है। तो यदि आप इसे निर्माण पर उसी तरह भरना चाहते हैं, तो आप string s(n, char()) पर विचार कर सकते हैं। लेकिन जब तक आप टी से अलग होने के लिए basic_string<T> का उपयोग नहीं करते हैं, तो आपका '\ 0' बस चाल करता है।

1

आकार बदलने से तत्वों को अनियमित नहीं किया जाता है। प्रलेखन के अनुसार: http://en.cppreference.com/w/cpp/string/basic_string/resize

s.resize(size) प्रत्येक संलग्न चरित्र को मूल्य-आरंभ करेगा। इससे आकार बदलने वाली स्ट्रिंग के प्रत्येक तत्व को '\0' पर प्रारंभ किया जाएगा।

आपको अपने विशिष्ट सी ++ कार्यान्वयन के प्रदर्शन अंतर को मापने के लिए वास्तव में यह तय करना होगा कि क्या कोई सार्थक अंतर है या नहीं।

एक अनुकूलित निर्माण के लिए विजुअल सी ++ द्वारा उत्पन्न मशीन को देखने के बाद, मैं आपको बता सकता हूं कि संस्करण के लिए कोड की मात्रा समान है। काउंटर अंतर्ज्ञानी क्या लगता है कि आकार बदलें() संस्करण तेजी से मेरे लिए मापा गया। फिर भी, आपको अपने स्वयं के कंपाइलर और मानक पुस्तकालय की जांच करनी चाहिए।

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