स्ट्रिंग बनाम स्टर्लिंगब्यूस्ट्रल


215

मैं Stringऔर StringBuilder( परस्पर StringBuilder) होने के बीच का अंतर समझता हूं, लेकिन क्या दोनों के बीच एक बड़ा प्रदर्शन अंतर है?

जिस प्रोग्राम पर मैं काम कर रहा हूं, उसमें बहुत सारे केस संचालित स्ट्रिंग अपेंडिक्स (500+) हैं। StringBuilderएक बेहतर विकल्प का उपयोग कर रहा है?

जवाबों:


236

हां, प्रदर्शन अंतर महत्वपूर्ण है। KB लेख देखें " विज़ुअल C # में स्ट्रिंग सुधार प्रदर्शन कैसे सुधारें "।

मैंने हमेशा स्पष्टता के लिए पहले कोड करने की कोशिश की है, और फिर बाद में प्रदर्शन के लिए अनुकूलित करें। यह बहुत आसान है इसे दूसरे तरीके से करने के अलावा! हालांकि, दोनों के बीच मेरे अनुप्रयोगों में बहुत बड़ा प्रदर्शन अंतर देखने के बाद, मैं अब इसके बारे में थोड़ा और ध्यान से सोचता हूं।

सौभाग्य से, यह आपके कोड पर प्रदर्शन विश्लेषण चलाने के लिए अपेक्षाकृत सरल है, यह देखने के लिए कि आप समय कहाँ खर्च कर रहे हैं, और फिर इसे संशोधित करने के लिए StringBuilderजहां आवश्यक हो।


44
अंगूठे का एक अच्छा नियम स्ट्रिंग्स का उपयोग करना है जब आप इसे बदलने के लिए नहीं जा रहे हैं और यदि आप इसे बदल रहे हैं तो स्ट्रिंगबर्स्ट का उपयोग करें।
टिम

31
मुझे यह जवाब बहुत पसंद है, खासकर प्रदर्शन से पहले स्पष्टता के लिए कोड करने की सलाह। डेवलपर्स के रूप में, हम कोड पढ़ने के रूप में ज्यादा या ज्यादा समय खर्च करते हैं।
स्कॉट लॉरेंस

आउटलॉ: मुझे लगता है कि इसका अपना जवाब बन जाना चाहिए, जिसे अलग से वोट दिया जाए, अगर मैं स्टैकऑवरफ्लो को सही तरीके से समझूं।
जे बाजुज़ी

2
मेरे अनुभव के आधार पर अगर आप 10-15 स्ट्रिंग को घुमाने की कोशिश कर रहे हैं तो आप स्ट्रिंग के साथ जा सकते हैं लेकिन यदि नहीं। तार से अधिक हैं तो स्ट्रिंग बिल्डर का उपयोग करें
पीयूष

3
यह अभी भी इस बात पर निर्भर करता है कि कोई इसका उपयोग कैसे करता है, वास्तव में मैं कोडिंग हॉरर की
एरिक फिलिप्स

56

यह स्पष्ट करने के लिए कि गिलियन ने 4 स्ट्रिंग के बारे में क्या कहा, अगर आपके पास ऐसा कुछ है:

string a,b,c,d;
 a = b + c + d;

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

हालाँकि, यदि आप जो कर रहे हैं वह करीब है:

string a,b,c,d;
 a = a + b;
 a = a + c;
 a = a + d;

फिर आपको स्पष्ट रूप से स्ट्रिंगब्यूलर का उपयोग करने की आवश्यकता है। .Net स्वचालित रूप से एक स्ट्रिंगब्यूलर नहीं बना सकता है, क्योंकि यह व्यर्थ होगा। प्रत्येक पंक्ति के अंत में, "a" को एक (अपरिवर्तनीय) स्ट्रिंग होना चाहिए, इसलिए इसे प्रत्येक पंक्ति पर एक StringBuilder को बनाना और निपटाना होगा। गति के लिए, आपको तब तक उसी स्ट्रिंगबेलर का उपयोग करने की आवश्यकता होगी जब तक आप निर्माण नहीं कर लेते:

string a,b,c,d;
StringBuilder e = new StringBuilder();
 e.Append(b);
 e.Append(c);
 e.Append(d);
 a = e.ToString();

5
कोई कारण नहीं है कि सी # संकलक को पहले से दूसरे नमूने का अलग तरीके से इलाज करने की आवश्यकता है। विशेष रूप से प्रत्येक पंक्ति के अंत में एक स्ट्रिंग का उत्पादन करने के लिए कोई दायित्व नहीं है। कंपाइलर आपके कहे अनुसार व्यवहार कर सकता है, लेकिन ऐसा करना किसी बाध्यता के तहत नहीं है।
कोडइन्कॉस्ट जूल

@CodesInChaos, एक अपरिवर्तनीय स्ट्रिंग चर को विशेष रूप से प्रत्येक पंक्ति के अंत में सौंपा जा रहा है, क्या यह स्ट्रिंग बनाने के लिए दायित्व नहीं बनाता है? हालांकि, मैं इस बात से सहमत हूं कि प्रत्येक व्यक्ति की लाइन को अलग-अलग तरीके से व्यवहार करने का कोई कारण नहीं है (और मुझे यकीन नहीं है कि अगर ऐसा होता है), तो प्रदर्शन का नुकसान वास्तविक स्थिति से होता है, हालांकि यह कोई फर्क नहीं पड़ता।
साब अमीनी

@SaebAmini - यदि aकोई स्थानीय चर है, और वह वस्तु जिसके संदर्भ किसी अन्य चर को नहीं सौंपे गए हैं (जो कि किसी अन्य सूत्र तक पहुँच योग्य हो सकता है), एक अच्छा अनुकूलक यह निर्धारित कर सकता है कि इस क्रम के दौरान किसी अन्य कोड द्वाराa प्रवेश नहीं किया गया है लाइनों; केवल मामलों का अंतिम मूल्य a। इसलिए यह कोड की उन तीन पंक्तियों को मान सकता है जैसे कि वे लिखे गए हों a = b + c + d;
टूलमेकरसेव

29

StringBuilder बेहतर है यदि आप अपने कोड पास में कई लूप, या कांटे कर रहे हैं ... हालाँकि, PURE प्रदर्शन के लिए, यदि आप एक स्ट्रिंग स्ट्रिंग घोषणा के साथ दूर हो सकते हैं , तो वह बहुत अधिक प्रदर्शन है।

उदाहरण के लिए:

string myString = "Some stuff" + var1 + " more stuff"
                  + var2 + " other stuff" .... etc... etc...;

की तुलना में अधिक प्रदर्शन है

StringBuilder sb = new StringBuilder();
sb.Append("Some Stuff");
sb.Append(var1);
sb.Append(" more stuff");
sb.Append(var2);
sb.Append("other stuff");
// etc.. etc.. etc..

इस मामले में, स्ट्रिंगबील्ड को अधिक बनाए रखा जा सकता है, लेकिन एकल स्ट्रिंग घोषणा की तुलना में अधिक प्रदर्शन नहीं है।

10 में से 9 बार हालांकि ... स्ट्रिंग बिल्डर का उपयोग करें।

एक साइड नोट पर: string + var भी अधिक परफॉरमेंस है कि string.Format एप्रोच (आम तौर पर) जो StringBuilder का आंतरिक रूप से उपयोग करता है (जब संदेह ... चेक रिफ्लेक्टर!)


17
काश, आपने कहा होता कि आप कैसे जानते हैं कि / कैसे सत्यापित करें।
क्रिस जुएल

2
आप रिफ्लेक्टर में प्रदर्शन को सत्यापित नहीं करते हैं: आप समय रिलीज कोड द्वारा प्रदर्शन को सत्यापित करते हैं, एक प्रोफाइलर के साथ विश्लेषण करते हैं और रिफ्लेक्टर के साथ स्पष्टीकरण चाहते हैं।
एल्बिन सुन्नान्बो

3
String.Format () का उपयोग करने पर विचार करें छोटी संख्या में छोटी संख्या को समेटने के लिए, विशेष रूप से लक्ष्य उपयोगकर्ता को दिखाने के लिए संदेशों को प्रारूपित करना है।
गैरी किंडल

1
यह बहुत बुरी जानकारी है। ("स्ट्रिंग myString अधिक प्रदर्शनकारी है") बिल्कुल भी सच नहीं है।
टॉम स्टिकेल 4'13 '

3
इस उत्तर की जानकारी गलत है। StringBuilder एक ही बयान में किए गए सहमति से थोड़ा तेज है; हालाँकि, आप दोनों के बीच केवल एक अंतर देखेंगे, यदि आप इसे सैकड़ों हज़ार बार करते हैं ( स्रोत )। जैसा कि स्रोत में कहा गया है, "यह सिर्फ मायने नहीं रखता है!"
डेविड शेरेट

25

गति का उपयोग करते समय गति में अंतर प्रदर्शित करने के लिए एक सरल उदाहरण Stringबनाम StringBuilder:

System.Diagnostics.Stopwatch time = new Stopwatch();
string test = string.Empty;
time.Start();
for (int i = 0; i < 100000; i++)
{
    test += i;
}
time.Stop();
System.Console.WriteLine("Using String concatenation: " + time.ElapsedMilliseconds + " milliseconds");

परिणाम:

स्ट्रिंग संघनन का उपयोग करना: 15423 मिलीसेकंड

StringBuilder test1 = new StringBuilder();
time.Reset();
time.Start();
for (int i = 0; i < 100000; i++)
{
    test1.Append(i);
}
time.Stop();
System.Console.WriteLine("Using StringBuilder: " + time.ElapsedMilliseconds + " milliseconds");

परिणाम:

StringBuilder का उपयोग करना: 10 मिलीसेकंड

नतीजतन, पहला पुनरावृत्ति 15423 एमएस लिया, जबकि दूसरा पुनरावृत्ति StringBuilder10 एमएस का उपयोग किया ।

यह मुझे लगता है कि उपयोग StringBuilderतेज है, बहुत तेज है।


24

यह मानदंड दर्शाता है कि 3 या उससे कम तारों के संयोजन के समय नियमित रूप से गति बढ़ रही है।

http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/

StringBuilder स्मृति उपयोग में बहुत महत्वपूर्ण सुधार कर सकती है, विशेष रूप से एक साथ 500 तार जोड़ने के आपके मामले में।

निम्नलिखित उदाहरण पर विचार करें:

string buffer = "The numbers are: ";
for( int i = 0; i < 5; i++)
{
    buffer += i.ToString();
}
return buffer;

स्मृति में क्या होता है? निम्नलिखित तार बनाए जाते हैं:

1 - "The numbers are: "
2 - "0"
3 - "The numbers are: 0"
4 - "1"
5 - "The numbers are: 01"
6 - "2"
7 - "The numbers are: 012"
8 - "3"
9 - "The numbers are: 0123"
10 - "4"
11 - "The numbers are: 01234"
12 - "5"
13 - "The numbers are: 012345"

स्ट्रिंग के अंत में उन पांच नंबरों को जोड़कर हमने 13 स्ट्रिंग ऑब्जेक्ट बनाए! और उनमें से 12 बेकार थे! वाह!

StringBuilder इस समस्या को ठीक करता है। यह एक "उत्परिवर्ती स्ट्रिंग" नहीं है जैसा कि हम अक्सर सुनते हैं ( .NET में सभी तार अपरिवर्तनीय हैं )। यह एक आंतरिक बफर, चार की एक सरणी रखकर काम करता है। अपेंड (कॉलिंग) या अपेंडलाइन () चार सरणी के अंत में रिक्त स्थान में स्ट्रिंग जोड़ता है; यदि सरणी बहुत छोटा है, तो यह एक नया, बड़ा सरणी बनाता है, और बफर को कॉपी करता है। इसलिए ऊपर दिए गए उदाहरण में, StringBuilder को केवल एक ही सरणी की आवश्यकता हो सकती है जिसमें स्ट्रिंग के लिए सभी 5 परिवर्धन शामिल हों- इसके बफर के आकार के आधार पर। आप StringBuilder बता सकते हैं कि इसका बफर कंस्ट्रक्टर में कितना बड़ा होना चाहिए।


2
माइनर नाइट: यह कहने में थोड़ा अजीब है कि "हमने 13 स्ट्रिंग ऑब्जेक्ट्स बनाए, और उनमें से 12 बेकार थे", और फिर कहने के लिए स्ट्रिंगबर्स्टल इस समस्या को ठीक करता है। आखिरकार, छह में से आपके पास बनाने के अलावा कोई विकल्प नहीं है; वे से कर रहे हैं i.ToString()। इसलिए StringBuilder के साथ, आपको अभी भी 6 + 1 तार बनाना होगा; इसने 7 तार बनाने के लिए 13 तार कम कर दिए। लेकिन वह अभी भी इसे देखने का गलत तरीका है; छह नंबर तार का निर्माण प्रासंगिक नहीं है। नीचे पंक्ति: आप बस द्वारा बनाए गए छह तार का उल्लेख नहीं करना चाहिए i.ToString(); वे दक्षता तुलना का हिस्सा नहीं हैं।
टूलमेकरसेव

12

हां, StringBuilderएक स्ट्रिंग पर बार-बार ऑपरेशन करते हुए बेहतर प्रदर्शन देता है। यह इसलिए है क्योंकि सभी परिवर्तन एक ही उदाहरण के लिए किए गए हैं ताकि यह एक नया उदाहरण बनाने के बजाय बहुत समय बचा सके String

स्ट्रिंग बनाम स्ट्रिंगर

  • String

    1. Systemनेमस्पेस के तहत
    2. अपरिवर्तनीय (केवल पढ़ने के लिए) उदाहरण
    3. प्रदर्शन में गिरावट तब होती है जब मूल्य में निरंतर परिवर्तन होता है
    4. सुरक्षित धागा
  • StringBuilder (म्यूटेबल स्ट्रिंग)

    1. System.Textनेमस्पेस के तहत
    2. परस्पर उदाहरण
    3. मौजूदा प्रदर्शन में नए बदलाव किए जाने के बाद से बेहतर प्रदर्शन दिखाता है

मजबूती से डॉटनेट भीड़ लेख की सिफारिश करें: स्ट्रिंग बनाम स्ट्रिंगबर्ल सी # में

संबंधित स्टैक ओवरफ्लो प्रश्न: स्ट्रिंग की म्यूटेबिलिटी जब स्ट्रिंग सी # में नहीं बदलती है?


12

स्ट्रिंग बनाम स्ट्रिंग बिल्डर:

सबसे पहले आपको यह जानना होगा कि ये दोनों वर्ग किस विधानसभा में रहते हैं?

इसलिए,

स्ट्रिंगSystem नेमस्पेस में मौजूद है ।

तथा

StringBuilderSystem.Text नामस्थान में मौजूद है ।

के लिए स्ट्रिंग घोषणा:

आपको Systemनामस्थान शामिल करना होगा । कुछ इस तरह। Using System;

तथा

के लिए StringBuilder घोषणा:

आपको System.textनामस्थान शामिल करना होगा । कुछ इस तरह। Using System.text;

अब वास्तविक प्रश्न पर आते हैं।

के बीच differene क्या है स्ट्रिंग और StringBuilder ?

इन दोनों में मुख्य अंतर यह है कि:

स्ट्रिंग अपरिवर्तनीय है।

तथा

StringBuilder परस्पर है।

तो अब चलिए अपरिवर्तनीय और परिवर्तनशील के बीच अंतर पर चर्चा करते हैं

उत्परिवर्तनीय:: का अर्थ है परिवर्तनीय।

अपरिवर्तनीय:: का अर्थ है परिवर्तनशील नहीं।

उदाहरण के लिए:

using System;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // String Example

            string name = "Rehan";
            name = name + "Shah";
            name = name + "RS";
            name = name + "---";
            name = name + "I love to write programs.";

            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah RS --- I love to write programs."
        }
    }
}

तो इस मामले में हम 5 बार एक ही वस्तु को बदलने जा रहे हैं।

तो स्पष्ट सवाल यह है कि! वास्तव में हुड के नीचे क्या होता है, जब हम एक ही स्ट्रिंग को 5 बार बदलते हैं।

यह वही होता है जब हम एक ही स्ट्रिंग को 5 बार बदलते हैं।

आइए आकृति को देखें।

यहां छवि विवरण दर्ज करें

explaination:

जब हम पहली बार इस वेरिएबल "नाम" को "रेहान" पर इनिशियलाइज़ करते हैं यानी string name = "Rehan" यह वेरिएबल स्टैक "नाम" पर बनता है और उस "रेहान" वैल्यू की ओर इशारा करता है। इस पंक्ति को निष्पादित करने के बाद: "name = name +" शाह "। संदर्भ चर अब उस ऑब्जेक्ट" रेहान "की ओर इशारा नहीं करता है जो अब" शाह "और इसी तरह इंगित करता है।

तो stringअपरिवर्तनीय अर्थ है कि एक बार जब हम मेमोरी में ऑब्जेक्ट बनाते हैं तो हम उन्हें बदल नहीं सकते हैं।

इसलिए जब हम nameचर को समाप्‍त करते हैं तो पिछली वस्‍तु मेमोरी में बनी रहती है और एक और नई स्ट्रिंग ऑब्जेक्ट बन जाती है ...

इसलिए उपरोक्त आंकड़े से हमारे पास पांच-ऑब्जेक्ट हैं चार-ऑब्जेक्ट को फेंक दिया जाता है उनका उपयोग बिल्कुल नहीं किया जाता है। वे स्मृति में बने रहते हैं और वे स्मृति की मात्रा को कम कर देते हैं। "कचरा कलेक्टर" इसके लिए जिम्मेदार है ताकि स्मृति से संसाधनों को साफ करें।

इसलिए स्ट्रिंग के मामले में कभी भी जब हम स्ट्रिंग को बार-बार हेरफेर करते हैं तो हमारे पास कुछ कई ऑब्जेक्ट होते हैं जिन्हें बनाया गया एनी मेमोरी में वहीं रहता है।

तो यह स्ट्रिंग वैरिएबल की कहानी है।

अब आइए StringBuilder Object की ओर देखें। उदाहरण के लिए:

using System;
using System.Text;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // StringBuilder Example

            StringBuilder name = new StringBuilder();
            name.Append("Rehan");
            name.Append("Shah");
            name.Append("RS");
            name.Append("---");
            name.Append("I love to write programs.");


            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah Rs --- I love to write programs."
        }
    }
}

तो इस मामले में हम 5 बार एक ही वस्तु को बदलने जा रहे हैं।

तो स्पष्ट सवाल यह है कि! वास्तव में हुड के नीचे क्या होता है, जब हम एक ही स्ट्रिंगबर्ल को 5 बार बदलते हैं।

यह वही होता है जब हम एक ही स्ट्रिंगबर्ल को 5 बार बदलते हैं।

आइए आकृति को देखें। यहां छवि विवरण दर्ज करें

व्याख्या: StringBuilder वस्तु के मामले में। आपको नई वस्तु नहीं मिलेगी। उसी ऑब्जेक्ट को मेमोरी में बदल दिया जाएगा, भले ही आप ऑब्जेक्ट एट को बदल दें 10,000 बार कहें कि हमारे पास अभी भी केवल एक ही स्ट्रिंग ऑब्जेक्ट होगा।

आपके पास कचरे की वस्तुओं या गैर-संदर्भित तार वाली वस्तुओं का एक बहुत कुछ नहीं है क्योंकि यह परिवर्तन क्यों हो सकता है। यह एक समय के साथ परिवर्तित होने का अर्थ है?

अंतर:

  • स्ट्रिंग सिस्टम नेमस्पेस में मौजूद है, जहां स्ट्रिंग स्ट्रिंगर के रूप में मौजूद है। सिस्टम नेमस्पेस।
  • स्ट्रिंग अपरिवर्तनीय है जहाँ StringBuilder उत्परिवर्ती है।

8

StringBuilder उपयोग किए गए अतिरिक्त मेमोरी की कीमत पर आवंटन और असाइनमेंट की संख्या को कम कर देता है। सही तरीके से उपयोग किए जाने पर, यह कंपाइलर की आवश्यकता को पूरी तरह से दूर कर सकता है, जब तक कि परिणाम नहीं मिल जाता है तब तक बड़े और बड़े तारों को आवंटित करना।

string result = "";
for(int i = 0; i != N; ++i)
{
   result = result + i.ToString();   // allocates a new string, then assigns it to result, which gets repeated N times
}

बनाम

String result;
StringBuilder sb = new StringBuilder(10000);   // create a buffer of 10k
for(int i = 0; i != N; ++i)
{
   sb.Append(i.ToString());          // fill the buffer, resizing if it overflows the buffer
}

result = sb.ToString();   // assigns once

5

किसी स्ट्रिंग या StringBuilder ऑब्जेक्ट के लिए एक कॉनएनेशन ऑपरेशन का प्रदर्शन इस बात पर निर्भर करता है कि मेमोरी एलोकेशन कितनी बार होता है। एक स्ट्रिंग संयोजन ऑपरेशन हमेशा मेमोरी आवंटित करता है, जबकि एक स्ट्रिंगबर्बले कॉन्टेक्नेशन ऑपरेशन केवल मेमोरी आवंटित करता है, अगर नए डेटा को समायोजित करने के लिए StringBuilder ऑब्जेक्ट बफर बहुत छोटा है। नतीजतन, स्ट्रिंग क्लास एक अवक्षेपण ऑपरेशन के लिए बेहतर होता है यदि एक निश्चित संख्या में स्ट्रिंग ऑब्जेक्ट्स को समतल किया जाता है। उस स्थिति में, संकलक द्वारा अलग-अलग संघनन संचालन को एकल ऑपरेशन में भी जोड़ा जा सकता है। एक स्ट्रिंग ऑपरेशन के लिए एक स्ट्रिंगबर्ब्यूबल ऑब्जेक्ट बेहतर होता है यदि स्ट्रिंग्स की एक मनमानी संख्या को समाप्‍त किया जाता है; उदाहरण के लिए, यदि एक लूप उपयोगकर्ता इनपुट के एक यादृच्छिक संख्या को समेटता है।

स्रोत: MSDN


3

StringBuilder कई गैर-स्थिर मूल्यों से एक स्ट्रिंग के निर्माण के लिए बेहतर है।

यदि आप बहुत सारे स्थिर मानों से एक स्ट्रिंग का निर्माण कर रहे हैं, जैसे कि HTML या XML दस्तावेज़ या पाठ के अन्य खंडों में मानों की कई पंक्तियाँ, तो आप एक ही स्ट्रिंग के साथ जुड़ने से दूर हो सकते हैं, क्योंकि लगभग सभी संकलक करते हैं "निरंतर तह", पार्स ट्री को कम करने की एक प्रक्रिया जब आपके पास निरंतर हेरफेर का एक गुच्छा होता है (इसका उपयोग तब भी किया जाता है जब आप कुछ लिखते हैं int minutesPerYear = 24 * 365 * 60)। और गैर-स्थिर मूल्यों के साथ सरल मामलों के लिए एक दूसरे से जुड़े, .NET कंपाइलर आपके कोड को कुछ इसी तरह कम कर देगा StringBuilder

लेकिन जब आपका अपीयर कंपाइलर द्वारा कुछ सरल करने के लिए कम नहीं किया जा सकता है, तो आप एक चाहते हैं StringBuilder। जैसा कि फ़िज़ल बताता है, कि लूप के अंदर होने की अधिक संभावना है।


2

मेरा मानना ​​है कि अगर आप 4 से अधिक तार एक साथ संलग्न करने की आवश्यकता है, तो StringBuilder तेज है। साथ ही यह कुछ ठंडी चीजें कर सकता है जैसे अपेंडलाइन।


2

.NET में, StringBuilder अभी भी तार जोड़ने से तेज है। मुझे पूरा यकीन है कि जावा में, वे केवल स्ट्रिंगबफ़र बनाते हैं हुड के नीचे जब आप तार जोड़ते हैं, तो वास्तव में कोई अंतर नहीं है। मुझे यकीन नहीं है कि उन्होंने अभी तक .NET में ऐसा क्यों नहीं किया है।



2

संघनन के लिए तार का उपयोग करने के क्रम पर एक रनटाइम जटिलता हो सकती है O(n^2)

यदि आप एक का उपयोग करते हैं StringBuilder, तो स्मृति की बहुत कम नकल होती है जिसे करना पड़ता है। साथ StringBuilder(int capacity)अगर आप अनुमान लगा सकते हैं कि कैसे बड़े अंतिम प्रदर्शन को बढ़ा सकते हैं Stringहोने जा रहा है। यहां तक ​​कि अगर आप सटीक नहीं हैं, तो आपको संभवतः केवल StringBuilderकुछ समय की क्षमता बढ़ानी होगी जो प्रदर्शन में भी मदद कर सकता है।


2

मैंने किसी भी स्ट्रिंग स्टोरेज के लिए उपयोग करने EnsureCapacity(int capacity)से StringBuilderपहले महत्वपूर्ण कॉल विधि के उपयोग से महत्वपूर्ण प्रदर्शन लाभ देखा है । मैं आमतौर पर तात्कालिकता के बाद कोड की लाइन पर कॉल करता हूं। इसका वैसा ही असर होता है जैसे आप StringBuilderइस तरह से तुरंत करते हैं:

var sb = new StringBuilder(int capacity);

यह कॉल समय से पहले आवश्यक मेमोरी आवंटित करता है, जो कई Append()ऑपरेशन के दौरान कम मेमोरी आवंटन का कारण बनता है । आपको एक शिक्षित अनुमान लगाना होगा कि आपको कितनी मेमोरी की आवश्यकता होगी, लेकिन अधिकांश अनुप्रयोगों के लिए यह बहुत मुश्किल नहीं होना चाहिए। मैं आमतौर पर थोड़ी बहुत मेमोरी के किनारे (हम 1k या तो बात कर रहे हैं)।


EnsureCapacityसिर्फ StringBuilderतात्कालिकता के बाद कॉल करने की आवश्यकता नहीं है। बस StringBuilderइस तरह तत्काल var sb = new StringBuilder(int capacity):।
डेविड फेरेंस्की रोगोजान

मुझे बताया गया था कि यह एक अभाज्य संख्या का उपयोग करने में मदद करता है।
कार्ल गजर्टसन

1

पिछले उत्तरों के आगे, पहली बात मैं हमेशा ऐसा करता हूं जब इस तरह के मुद्दों के बारे में सोचकर एक छोटा परीक्षण अनुप्रयोग बनाना होता है। इस ऐप के अंदर, दोनों परिदृश्यों के लिए कुछ समय परीक्षण करें और अपने लिए देखें कि कौन जल्दी है।

IMHO, 500+ स्ट्रिंग प्रविष्टियों को जोड़कर निश्चित रूप से StringBuilder का उपयोग करना चाहिए।


1

StringBuilder वास्तव में दोनों अपरिवर्तनीय हैं, StringBuilder ने बफ़र्स में बनाया है जो इसके आकार को अधिक कुशलता से प्रबंधित करने की अनुमति देता है। जब StringBuilder को आकार देने की आवश्यकता होती है, जब इसे ढेर पर फिर से आवंटित किया जाता है। डिफ़ॉल्ट रूप से यह 16 वर्णों के आकार का है, आप इसे कंस्ट्रक्टर में सेट कर सकते हैं।

जैसे।

StringBuilder sb = नया StringBuilder (50);


2
निश्चित नहीं है कि आप समझते हैं कि अपरिवर्तनीय का क्या अर्थ है। स्ट्रिंग्स अपरिवर्तनीय हैं, उन्हें बदला नहीं जा सकता। कुछ भी "परिवर्तित" वास्तव में सिर्फ इतना है कि पुराने मूल्य ढेर पर रहता है बिना किसी सूचक के इसका पता लगाने के लिए। StringBuilder (परिवर्तनशील) हीप पर संदर्भ प्रकार है, हीप को पॉइंटर बदल दिया जाता है और इस परिवर्तन के लिए जगह का आवंटन होता है।
टॉम स्टिकेल

1

स्ट्रिंग संघनन आपको अधिक खर्च करेगा। जावा में, आप अपनी आवश्यकता के आधार पर या तो स्ट्रिंगबफर या स्ट्रिंगबर्ल का उपयोग कर सकते हैं। यदि आप एक सिंक्रनाइज़ और थ्रेड सुरक्षित कार्यान्वयन चाहते हैं, तो StringBuffer पर जाएँ। यह स्ट्रिंग के संगति से तेज होगा।

यदि आपको सिंक्रनाइज़ या थ्रेड सुरक्षित कार्यान्वयन की आवश्यकता नहीं है, तो StringBuilder के लिए जाएं। यह स्ट्रिंग संघनन की तुलना में तेज़ होगा और स्ट्रिंगबफ़र की तुलना में भी तेज़ होगा क्योंकि उनका कोई सिंक्रोनाइज़ेशन ओवरहेड नहीं है।


0

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


0

यदि आप बहुत अधिक स्ट्रिंग संयोजन कर रहे हैं, तो स्ट्रिंग स्ट्रिंग का उपयोग करें। जब आप एक स्ट्रिंग के साथ सम्‍मिलित होते हैं, तो आप अधिक मेमोरी का उपयोग करके, हर बार एक नया स्ट्रिंग बनाते हैं।

एलेक्स


0

अंगूठे के एक सामान्य नियम के रूप में, अगर मुझे स्ट्रिंग के मूल्य को एक से अधिक बार सेट करना है, या यदि स्ट्रिंग के लिए कोई भी अपेंडिक्स हैं, तो उसे स्ट्रिंग बिल्डर होने की आवश्यकता है। मैंने उन अनुप्रयोगों को देखा है जो मैंने अतीत में स्ट्रिंग बिल्डरों के बारे में जानने से पहले लिखे हैं, जिनमें एक विशाल मेमोरी फुट प्रिंट है जो बस बढ़ते और बढ़ते हुए लगता है। स्ट्रिंग बिल्डर का उपयोग करने के लिए इन कार्यक्रमों को बदलने से मेमोरी उपयोग में काफी कमी आती है। अब मैं स्ट्रिंग बिल्डर की कसम खाता हूं।


0

मेरा दृष्टिकोण हमेशा 4 या अधिक स्ट्रिंग्स को समाप्‍त करने पर StringBuilder का उपयोग करने के लिए किया गया है या जब मुझे पता नहीं है कि कॉनकैनेटेशन कैसे हो सकते हैं।

अच्छा प्रदर्शन संबंधित लेख यहाँ पर


0

StringBuilder काफी अधिक कुशल है लेकिन आप उस प्रदर्शन को तब तक नहीं देखेंगे जब तक कि आप बड़ी मात्रा में स्ट्रिंग संशोधन नहीं कर रहे हैं।

प्रदर्शन का एक उदाहरण देने के लिए नीचे कोड का एक त्वरित हिस्सा है। जैसा कि आप देख सकते हैं कि वास्तव में आप केवल बड़े पुनरावृत्तियों में आने पर एक प्रमुख प्रदर्शन में वृद्धि देखना शुरू करते हैं।

जैसा कि आप देख सकते हैं कि 200,000 पुनरावृत्तियों को 22 सेकंड लगे, जबकि 1 मिलियन पुनरावृत्तियों का उपयोग StringBuilderलगभग तत्काल था।

string s = string.Empty;
StringBuilder sb = new StringBuilder();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 50000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 200000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();
Console.WriteLine("Beginning Sb append at " + DateTime.Now.ToString());

for (int i = 0; i <= 1000000; i++)
{
    sb.Append("A");
}
Console.WriteLine("Finished Sb append at " + DateTime.Now.ToString());

Console.ReadLine();

उपरोक्त कोड का परिणाम:

शुरुआत स्ट्रिंग + पर 28/01/2013 16:55:40 पर।

28/01/2013 को 16:55:40 पर स्ट्रिंग समाप्त।

शुरुआत स्ट्रिंग + पर 28/01/2013 16:55:40 पर।

28/01/2013 16:56:02 बजे स्ट्रिंग + समाप्त हो गया।

शुरुआत Sb 28/01/2013 16:56:02 पर।

समाप्त Sb 28/01/2013 16:56:02 पर संलग्न।


1
यदि स्ट्रिंग बिल्डर इतना शक्तिशाली है तो हमारे पास स्ट्रिंग अस्तित्व में क्यों है। हम स्ट्रिंग को पूरी तरह से मिटा क्यों नहीं देते। मैंने यह सवाल इसलिए पूछा ताकि आप मुझे स्ट्रिंग ऑफ
अनब्रेकेबल

-2

StringBuilder एक मेमोरी स्टैंड बिंदु से बेहतर प्रदर्शन करेगी। प्रसंस्करण के लिए, निष्पादन के समय में अंतर नगण्य हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.