2008-12-16 18 views
12

स्ट्रिंग अपरिवर्तनीयता कथन द्वारा या किसी कथन के भीतर तारों द्वारा काम करती है?स्ट्रिंग अपरिवर्तनीयता

उदाहरण के लिए, मैं समझता हूं कि निम्न कोड ढेर पर दो तार आवंटित करेगा।

string s = "hello "; 
s += "world!"; 

कचरा इकट्ठा होने तक "हैलो" ढेर पर रहेगा; और अब संदर्भ "हैलो दुनिया!" ढेर पर हालांकि, निम्नलिखित पंक्ति कितनी तार ढेर पर आवंटित करती है ... 1 या 2? साथ ही, परिणाम सत्यापित करने के लिए कोई उपकरण/तरीका है? क्यों दूसरे उदाहरण ही कभी एक स्ट्रिंग है

string s = "goodbye " + "cruel world!"; 

उत्तर

21

संकलक स्ट्रिंग संयोजन है, जो के लिए विशेष उपचार है। और "इंटर्निंग" का अर्थ है कि भले ही आप इस लाइन को 20000 बार चलाते हैं, फिर भी केवल 1 स्ट्रिंग है।

परिणाम परीक्षण पुन ... सबसे आसान तरीका है (इस मामले में) परावर्तक में देखने के लिए शायद है:

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    .maxstack 1 
    .locals init (
     [0] string s) 
    L_0000: ldstr "goodbye cruel world!" 
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: call void [mscorlib]System.Console::WriteLine(string) 
    L_000c: ret 
} 

आप देख सकते हैं (ldstr), संकलक पहले से ही आप के लिए यह किया है।

+0

निष्पक्ष होने के लिए: इस मामले में स्ट्रिंग के दोनों हिस्सों को संकलित समय पर जाना जाता है। यदि उसमें से किसी भी हिस्से को रन-टाइम तक इंतजार करना पड़ा तो आप कुछ बहुत अलग आईएल देखेंगे। –

+1

@ जोएल - हाँ, लेकिन यह सवाल था। –

-1

यदि संकलक "बुद्धिमान" है, तो यह केवल "अलविदा क्रूर दुनिया" के साथ एक स्ट्रिंग होगा!

+0

यह है, और यह करता है। मेरे जवाब में आईएल देखें। –

+0

आंतरिक पूल के लिए Google भी करें – JamesSugrue

0

असल में, शायद 3. "अलविदा" के लिए एक कॉन्स स्ट्रिंग, "क्रूर दुनिया" के लिए एक कॉन्स स्ट्रिंग, और फिर परिणाम के लिए एक नई स्ट्रिंग।

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

+0

वह वह नेट है जिसके लिए वह पूछ रहा है। –

0

स्ट्रिंग्स के बारे में आपको "पता" पर भरोसा न करें। आप स्ट्रिंग के कार्यान्वयन के लिए स्रोत कोड देख सकते हैं। उदाहरण के लिए आपका उदाहरण:

string s = "goodbye " + "cruel world!"; 

जावा में एक एकल स्ट्रिंग आवंटित की जाएगी। जावा कुछ सुंदर प्यारा चाल बजाता है और बाहर निकलना मुश्किल होगा - जब तक आपको आवश्यकता न हो तब तक अनुकूलित न करें!

वर्तमान में तथापि, जहाँ तक मुझे पता है, इस का उपयोग करते हुए:

String s=""; 
for(int i=0;i<1000;i++) 
    s+=" "; 

एक 1000 अंतरिक्ष स्ट्रिंग अभी भी बनाने के लिए अत्यंत अक्षम

एक पाश में जोड़ बहुत बुरा है हो जाता है, लेकिन अन्यथा यह है संभवतः स्ट्रिंगबिल्डर के रूप में कुशल।

+0

जो कि एक बहुत बड़ा "अन्यथा" है ... स्ट्रिंगबिल्डर दोगुना उपयोग करेगा, इसलिए 1000 प्रतियों (टेलीस्कोपिंग) के बजाय <10 आकार बदलता है। –

+0

ठीक है, तो अभी के लिए, बड़े loops में तारों में संलग्न होने से बचें, लेकिन अन्यथा इसके बारे में तनाव नहीं है। यहां तक ​​कि, अधिकांश कोड के लिए मैं इसके बारे में चिंता नहीं करता जब तक कि यह प्रदर्शन को प्रभावित नहीं कर लेता। –

3

शाब्दिक तार कर रहे हैं interned इसका मतलब यह है "hello " करता है कि नहीं ढेर पर रहते हैं, लेकिन डेटा खंड में [टिप्पणी देखें] प ¤ के (और इस प्रकार कचरा संग्रहण के योग्य नहीं है), एक ही "world" के लिए चला जाता है, "hello world" के लिए जो भी इंटर्न किया जा सकता है, यदि संकलक पर्याप्त स्मार्ट है।

"goodbye cruel world" इंटर्न किया जाएगा क्योंकि स्ट्रिंग शाब्दिक concatenation कुछ संकलक द्वारा इलाज किया जाता है।


संपादित करें: मैं डेटा खंड कथन के बारे में यकीन नहीं है, तो अधिक जानकारी के लिए this question देखते हैं।

+1

आंतरिक स्ट्रिंग वास्तव में ढेर पर हैं जैसे कि हर दूसरे संदर्भ प्रकार .NET में। –

0

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

0

यदि आप सिर्फ एक या दो स्ट्रिंग कॉन्सटेनेशन करने जा रहे हैं तो मैं इसके बारे में चिंता नहीं करूंगा।

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

+0

इसे .NET –

+0

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

0

यदि यह सिर्फ एक पंक्ति में नहीं है, तो स्ट्रिंगबफर में पहली स्ट्रिंग बनाने, संगतता करने और परिणाम स्ट्रिंग को वापस करने के द्वारा दो स्ट्रिंग्स का संयोजन पूरा किया जा सकता है।

StringBuffer बनाना अपने आप को overkill की तरह लग सकता है, लेकिन यह क्या anyway.-

+0

मुझे लगता है कि आपका मतलब स्ट्रिंगबिल्डर है –

0

हर तरह समय से पहले ही अनुकूलित न करें तक होने जा रहा है, लेकिन छूट नहीं है कितनी बुरी तरह से performant स्ट्रिंग concatonations हो सकता है। यह वस्तु निर्माण नहीं है, लेकिन जीसी काम करता है जो इसका कारण बनता है।

पर एक प्रयोगशाला है (एएसपी.नेट एस्केलेशन इंजीनियर) Tess Ferrnandez's ब्लॉग जो how string concatonation can bring a server to its knees का एक (बल्कि चरम, दिया गया) उदाहरण दिखाता है।