StringBuilder और StringBuffer के बीच अंतर


1577

मुख्य अंतर क्या है StringBufferऔर StringBuilder? क्या इनमें से किसी एक पर निर्णय लेते समय कोई प्रदर्शन मुद्दे हैं?

जवाबों:


1665

StringBufferसिंक्रनाइज़ है, StringBuilderनहीं है।


239
और StringBuilder का मतलब StringBuffer के लिए प्रतिस्थापन में एक बूंद के रूप में है जहाँ सिंक्रनाइज़ेशन की आवश्यकता नहीं है
जोएल

95
और तुल्यकालन वस्तुतः आवश्यक नहीं है। यदि कोई StringBuilder पर सिंक्रनाइज़ करना चाहता है, तो वे कोड के पूरे ब्लॉक को एक सिंक्रोनाइज़ (sb) {} उदाहरण के साथ घेर सकते हैं
Locka

23
@locka मैं तर्क दूंगा कि StringBuffer एक अच्छा विचार नहीं है (जब तक कि आपके पास एक API न हो जिसकी आवश्यकता है) vanillajava.blogspot.de/2013/04/…
पीटर लॉरी

8
केवल एक स्ट्रिंगरफ़र के लिए मैं जो जगह देख रहा हूँ वह आउटपुट की तरह कंसोल और विभिन्न लॉगिंग यूटिलिटी है: कई थ्रेड संघर्ष में आउटपुट कर सकते हैं। चूंकि आप 2 आउटपुट नहीं मिलाते हैं ... लेकिन आमतौर पर StringBuffer स्तर पर सिंक्रोनाइज़ करना बहुत कम स्तर है, आप किसी ऐपेंडर पर सिंक्रोनाइज़ करना चाहेंगे जैसे कि levela इसलिए लॉक का उत्तर सबसे अच्छा है और StringBuffer को अपदस्थ किया जाना चाहिए। यह newbies के साथ कोड समीक्षा समय को बचाएगा।
रेमी मोरिन

20
जो लोग इन दोनों को मिलाते हैं उनके लिए अच्छा महामारी - बूफर पहले, पुराने और इसलिए सिंक्रनाइज़ कार्यान्वयन था। नया बिल्डर वर्ग बिल्डर पैटर्न का उपयोग करता है और अतुल्यकालिक है।
दत्ताटेक

728

StringBuilderसे तेज है StringBufferक्योंकि यह नहीं है synchronized

यहाँ एक साधारण बेंचमार्क परीक्षण है:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

एक परीक्षण चलाने की संख्या देता है 2241 msके लिए StringBufferबनाम 753 msके लिए StringBuilder


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

7
आपको पहले गर्म करने की आवश्यकता है। यह परीक्षण StringBuffer के लिए अनुचित है। इसके अलावा, यह अच्छा होगा यदि यह वास्तव में कुछ जोड़ रहा है। वास्तव में, मैंने परीक्षण को फ़्लिप किया, और एक यादृच्छिक स्ट्रिंग को जोड़ दिया और विपरीत परीक्षण प्राप्त किया। यह कहना आसान है, कि कोई साधारण बेंचमार्क पर भरोसा नहीं कर सकता है। इसके विपरीत स्ट्रींगबफ़र तेज़ है। StringBuilder बनाम 3699 के लिए 5164 StringBuffer के लिए hastebin.com/piwicifami.avrasm
एमएमएम

75
यह पहली बार है जब मैं --> 0एक पाश में देख रहा हूं । मुझे एक पल का एहसास हुआ कि इसका क्या मतलब है। क्या यह कुछ ऐसा है जो वास्तव में सामान्य ...; i > 0; i--वाक्य रचना के बजाय व्यवहार में उपयोग किया जाता है ?
रायमुंड क्रमर

19
यह i -->वास्तव में कष्टप्रद वाक्यविन्यास-वार है ... मुझे लगा कि यह ASCII कला के बारे में टिप्पणियों के कारण पहली बार में एक तीर था।
समीर पुरी

14
अन्य विभिन्न परिणामों के साथ समाप्त होते हैं: alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html । बेंचमार्क वास्तव में जेएमएच के साथ होना चाहिए, न कि एक साधारण के main()साथ, आपका बेंचमार्क अनुचित है। कोई वार्मअप नहीं है।
लुकास एडर

249

मूल रूप से, StringBufferतरीके सिंक्रनाइज़ किए जाते हैं , जबकि StringBuilderनहीं हैं।

ऑपरेशन "लगभग" समान हैं, लेकिन एक ही थ्रेड में सिंक्रनाइज़ किए गए तरीकों का उपयोग करना ओवरकिल है।

इसके बारे में बहुत सुंदर है।

StringBuilder एपीआई से उद्धरण :

यह वर्ग [स्ट्रिंगब्यूएस्टल] स्ट्रिंग स्ट्रिंगर के साथ संगत एपीआई प्रदान करता है, लेकिन सिंक्रनाइज़ेशन की कोई गारंटी नहीं है । इस वर्ग को स्ट्रिंग-बफ़र के लिए ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग करने के लिए डिज़ाइन किया गया है, जहाँ स्ट्रिंग बफर का उपयोग एकल थ्रेड द्वारा किया जा रहा था (जैसा कि आमतौर पर होता है)। जहां संभव हो, यह अनुशंसा की जाती है कि इस वर्ग का उपयोग स्ट्रिंगबफ़र की प्राथमिकता में किया जाए क्योंकि यह अधिकांश कार्यान्वयनों के तहत तेज़ होगा।

इसलिए इसे स्थानापन्न करने के लिए बनाया गया था।

उसी के साथ हुआ Vectorऔर ArrayList


1
इसके अलावा के साथ Hashtableऔर HashMap
shmosel

176

लेकिन एक उदाहरण की मदद से स्पष्ट अंतर प्राप्त करने की आवश्यकता है?

StringBuffer या StringBuilder

बस का उपयोग करें StringBuilderजब तक आप वास्तव में धागे के बीच एक बफर साझा करने की कोशिश कर रहे हैं। StringBuilderमूल सिंक्रोनाइज़्ड StringBufferक्लास का छोटा भाई (कम ओवरहेड = अधिक कुशल) छोटा भाई है ।

StringBufferपहले आया। सूर्य सभी परिस्थितियों में शुद्धता से चिंतित था, इसलिए उन्होंने इसे केवल मामले में धागा-सुरक्षित बनाने के लिए इसे सिंक्रनाइज़ किया।

StringBuilderबाद में आया। उपयोग के अधिकांश StringBufferएकल-सूत्र थे और अनावश्यक रूप से सिंक्रनाइज़ेशन की लागत का भुगतान करते थे।

के बाद से StringBuilderएक है ड्रॉप-में प्रतिस्थापन के लिए StringBufferतुल्यकालन के बिना, वहाँ कोई उदाहरण के बीच मतभेद नहीं होगा।

यदि आप थ्रेड्स के बीच साझा करने का प्रयास कर रहे हैं , तो आप उपयोग कर सकते हैं StringBuffer, लेकिन विचार करें कि क्या उच्च-स्तरीय सिंक्रोनाइज़ेशन आवश्यक है, उदाहरण के लिए, शायद स्ट्रिंगबफ़र का उपयोग करने के बजाय, क्या आपको उन तरीकों को सिंक्रनाइज़ करना चाहिए जो स्ट्रिंगब्यूलर का उपयोग करते हैं।


14
पहला अच्छा जवाब !! मुद्दा यह है कि "जब तक आप थ्रेड्स के बीच एक बफर साझा नहीं कर रहे हैं"
एलेक्सविन

1
बहुत विस्तृत जवाब!
राऊल

81

पहले समानताएं देखने दें : StringBuilder और StringBuffer दोनों ही एक-दूसरे के अनुकूल हैं। इसका मतलब है कि आप उनमें से सामग्री को उसी स्थान पर बदल सकते हैं।

अंतर : स्ट्रिंगबफ़र परस्पर और साथ ही सिंक्रनाइज़ है। जहाँ StringBuilder उत्परिवर्तित है लेकिन डिफ़ॉल्ट रूप से सिंक्रनाइज़ नहीं है।

सिंक्रनाइज (सिंक्रनाइजेशन) का अर्थ : जब कोई चीज सिंक्रोनाइज होती है, तो कई थ्रेड्स एक्सेस कर सकते हैं, और इसे किसी भी समस्या या साइड इफेक्ट से जोड़ सकते हैं। StringBuffer सिंक्रनाइज़ है, इसलिए आप इसे किसी भी समस्या के साथ कई थ्रेड के साथ उपयोग कर सकते हैं।

कब कौन सा उपयोग करना है? StringBuilder: जब आपको एक स्ट्रिंग की आवश्यकता होती है, जो कि परिवर्तनीय हो सकती है, और केवल एक धागा इसे एक्सेस और संशोधित कर रहा है। स्ट्रिंगरबफ़र: जब आपको एक स्ट्रिंग की आवश्यकता होती है, जो कि परिवर्तनीय हो सकती है, और कई धागे इसे एक्सेस और संशोधित कर रहे हैं।

नोट : StringBuffer का उपयोग अनावश्यक रूप से न करें, अर्थात, इसका उपयोग न करें यदि केवल एक धागा इसे संशोधित और एक्सेस कर रहा है क्योंकि इसमें सिंक्रनाइज़ेशन के लिए बहुत सारे लॉकिंग और अनलॉकिंग कोड हैं जो अनावश्यक रूप से CPU समय लेगा। जब तक आवश्यक न हो ताले का उपयोग न करें।


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

57

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

यहाँ मेरा परीक्षण है (बेंचमार्क नहीं, सिर्फ एक परीक्षण):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

परिणाम:
तार: 319740
बफर: 23
बिल्डर: 7!

इसलिए बिल्डर्स बफ़र्स की तुलना में तेज़ हैं, और WAY स्ट्रेंथ कॉन्टैक्सेशन से तेज़ हैं। अब कई थ्रेड के लिए एक एक्सेक्यूटर का उपयोग करते हैं :

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

अब StringBuffers 100000 एपेंड के लिए 157 ms लेते हैं । यह एक ही परीक्षण नहीं है, लेकिन पिछले 37 एमएस की तुलना में, आप सुरक्षित रूप से मान सकते हैं कि स्ट्रिंगबफर्स ​​एपेंडर्स मल्टीथ्रेडिंग उपयोग के साथ धीमी हैं । कारण यह है कि जेआईटी / हॉटस्पॉट / कंपाइलर / कोई चीज अनुकूलन करता है जब यह पता लगाता है कि ताले की जाँच की कोई आवश्यकता नहीं है।

लेकिन StringBuilder के साथ, आपके पास java.lang.ArrayIndexOutOfBoundsException है , क्योंकि एक समवर्ती धागा कुछ जोड़ने की कोशिश करता है जहां यह नहीं होना चाहिए।

निष्कर्ष यह है कि आपको StringBuffers का पीछा करने की आवश्यकता नहीं है। और जहां आपके पास थ्रेड्स हैं, कुछ नैनोसेकंड हासिल करने की कोशिश करने से पहले सोचें कि वे क्या कर रहे हैं।


5
आप "t0 = System.currentTimeMillis ();" करना भूल गए हैं StringBuilder परीक्षण करने से पहले। तो स्ट्रिंगबर्ल के लिए प्रदर्शित आंकड़ा वास्तव में स्ट्रिंगबफ़र और स्ट्रिंगर परीक्षण चलाने में लगने वाला समय है। इस पंक्ति को जोड़ें और आप देखेंगे कि StringBuilder दो तीरों के बारे में तेजी से है।
गेना बल्लेबाज़

ध्यान दें कि withString+="some string"+i+" ; ";अन्य दो छोरों के बराबर नहीं है और इसलिए यह उचित तुलना नहीं है।
डेव जार्विस

सही, सही। सोचा तार अभी भी बहुत धीमी है।
निकोलस ज़ोज़ोल

क्या आप अधिक बता सकते हैं कि क्यों ArrayIndexOutOfBoundsException StringBuilder के
Alireza Fattahi

आपको बेंचमार्क के लिए जेएमएच का उपयोग करना चाहिए। आपका बेंचमार्क वास्तव में गलत है।
लुकास ईडर

42

StringBuilder को Java 1.5 में पेश किया गया था ताकि यह पहले JVM के साथ काम न करे।

से Javadocs :

StringBuilder वर्ग StringBuffer के साथ संगत API प्रदान करता है, लेकिन सिंक्रनाइज़ेशन की कोई गारंटी नहीं है। इस वर्ग को स्ट्रिंग-बफ़र के लिए ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग करने के लिए डिज़ाइन किया गया है, जहाँ स्ट्रिंग बफर का उपयोग एक ही धागे द्वारा किया जा रहा था (जैसा कि आमतौर पर होता है)। जहां संभव हो, यह अनुशंसा की जाती है कि इस वर्ग का उपयोग स्ट्रिंगबफ़र के लिए प्राथमिकता में किया जाए क्योंकि यह अधिकांश कार्यान्वयनों के तहत तेज़ होगा।


13
1.4 इसके सेवा जीवन का अंत है, इसलिए यह शायद ही पूर्व 1.5 के बारे में चिंता करने योग्य है।
टॉम हॉकिन -

@ टॉमहॉटिन-टैक्लाइन जरूरी नहीं - पूर्व 1.4 पर उद्यम उत्पाद हैं जो हम में से ज्यादातर दैनिक उपयोग करते हैं। इसके अलावा ब्लैकबेरी जावा 1.4 पर आधारित है और यह अभी भी बहुत चालू है।
रिचर्ड ले मेसियर

और सीडीसी और सीएलडीसी नहीं है StringBuilder
जिन क्वायन

37

बहुत अच्छा सवाल है

यहाँ अंतर हैं, मैंने देखा है:

स्ट्रिंगर:

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

आम बात :-

दोनों में समान हस्ताक्षर वाले तरीके हैं। दोनों परस्पर हैं।


23

StringBuffer

  • सिंक्रनाइज़ इसलिए थ्रेडसेफ़
  • थ्रेड सुरक्षित इसलिए धीमा

StringBuilder

  • जावा 5.0 में पेश किया गया
  • अतुल्यकालिक इसलिए तेज और कुशल
  • उपयोगकर्ता स्पष्ट रूप से इसे सिंक्रनाइज़ करने की आवश्यकता है, अगर वह चाहता है
  • आप इसे StringBufferबिना किसी अन्य परिवर्तन के साथ बदल सकते हैं

नोट: केवल एकल ऑपरेशन थ्रेड-सुरक्षित हैं, कई ऑपरेशन नहीं हैं। जैसे अगर आप फोन appendदो बार, या appendऔर toStringनहीं सुरक्षित नहीं है।
पीटर लॉरी

22

StringBuilder धागा सुरक्षित नहीं है। स्ट्रिंग बफ़र है। अधिक जानकारी यहाँ

संपादित करें: प्रदर्शन के लिए, हॉटस्पॉट किक के बाद , स्ट्रिंगबुलस्टार विजेता है। हालांकि, छोटे पुनरावृत्तियों के लिए, प्रदर्शन अंतर नगण्य है।


21

StringBuilderऔर StringBufferलगभग समान हैं। अंतर यह है कि StringBufferसिंक्रनाइज़ किया गया है और StringBuilderनहीं है। हालांकि, StringBuilderकी तुलना में तेज है StringBuffer, प्रदर्शन में अंतर बहुत कम है। StringBuilderसूर्य का प्रतिस्थापन है StringBuffer। यह सिर्फ सभी सार्वजनिक तरीकों से सिंक्रनाइज़ेशन से बचा जाता है। इसके बजाय, उनकी कार्यक्षमता समान है।

अच्छे उपयोग का उदाहरण:

यदि आपका पाठ बदलने जा रहा है और कई थ्रेड्स द्वारा उपयोग किया जाता है, तो इसका उपयोग करना बेहतर है StringBuffer। यदि आपका पाठ बदलने जा रहा है, लेकिन एक एकल थ्रेड द्वारा उपयोग किया जाता है, तो उपयोग करें StringBuilder


19

StringBuffer

StringBuffer एक है जिसका अर्थ है कि वस्तु का मूल्य बदल सकता है। StringBuffer के माध्यम से बनाई गई वस्तु हीप में संग्रहीत होती है। StringBuffer में StringBuilder जैसी ही विधियाँ हैं, लेकिन StringBuffer में प्रत्येक विधि सिंक्रनाइज़ की गई है जो StringBuffer थ्रेड सुरक्षित है।

इस वजह से यह एक ही विधि से एक साथ दो थ्रेड्स को एक्सेस करने की अनुमति नहीं देता है। प्रत्येक विधि को एक समय में एक थ्रेड द्वारा पहुँचा जा सकता है।

लेकिन थ्रेड सेफ होने के कारण नुकसान भी है क्योंकि थ्रेडबफ़र हिट के प्रदर्शन के कारण थ्रेड सेफ प्रॉपर्टी है। इस प्रकार StringBuilder प्रत्येक कक्षा के समान तरीकों को कॉल करते समय StringBuffer से तेज है।

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

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder StringBuffer के समान है, अर्थात यह ऑब्जेक्ट को ढेर में संग्रहीत करता है और इसे संशोधित भी किया जा सकता है। StringBuffer और StringBuilder के बीच मुख्य अंतर यह है कि StringBuilder भी थ्रेड सुरक्षित नहीं है। StringBuilder तेज है क्योंकि यह थ्रेड सुरक्षित नहीं है।

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

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

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


StringBuilder अपरिवर्तनीय है और String प्रकार परस्पर है
Brinda Rathod

मैं इस बात से सहमत नहीं हूँ कि स्ट्रिंग्स और स्ट्रिंगरबिल्डर्स "तेज़" हैं और स्ट्रिंगबफ़र "बहुत धीमे" हैं। उपरोक्त उत्तर देखें।
FireCubez

17

String एक अपरिवर्तनीय है।

StringBuffer एक परिवर्तनशील और सिंक्रनाइज़ है।

StringBuilder भी परिवर्तनशील है, लेकिन इसकी सिंक्रनाइज़ नहीं है।


इसके अतिरिक्त StringBuffer इस थ्रेड सुरक्षित डेटा को एक्सेस करने के लिए थ्रेड्स को लॉक करता है, इसीलिए ऑपरेशन धीरे-धीरे होता है। StringBuilder धागे को लॉक नहीं करती है और यह मल्टी थ्रेडिंग तरीके से चलती है इसलिए यह तेज़ है। स्ट्रिंग - जब आपको समवर्ती स्ट्रिंग की आवश्यकता नहीं होती है, तो यह अच्छा तरीका है, लेकिन जब आपको इसकी आवश्यकता होती है, तो आप स्ट्रिंग स्ट्रिंग का उपयोग करें -> क्योंकि स्ट्रिंग हर बार नए ऑब्जेक्ट को ढेर में बनाता है, लेकिन स्ट्रिंगब्यूरी उसी वस्तु को लौटाता है ...
मूसा

11

जावाडोक अंतर बताते हैं:

यह वर्ग StringBuffer के साथ संगत API प्रदान करता है, लेकिन सिंक्रनाइज़ेशन की कोई गारंटी नहीं है। इस वर्ग को स्ट्रिंग-बफ़र के लिए ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग करने के लिए डिज़ाइन किया गया है, जहाँ स्ट्रिंग बफर का उपयोग एक ही धागे द्वारा किया जा रहा था (जैसा कि आमतौर पर होता है)। जहां संभव हो, यह अनुशंसा की जाती है कि इस वर्ग का उपयोग स्ट्रिंगबफ़र के लिए प्राथमिकता में किया जाए क्योंकि यह अधिकांश कार्यान्वयनों के तहत तेज़ होगा।


10

StringBuilder(जावा 5 में पेश किया गया) समान है StringBuffer, सिवाय इसके कि इसके तरीके सिंक्रनाइज़ नहीं हैं। इसका मतलब है कि बाद के मुकाबले इसका प्रदर्शन बेहतर है, लेकिन खामी यह है कि यह थ्रेड-सुरक्षित नहीं है।

अधिक जानकारी के लिए ट्यूटोरियल पढ़ें ।


6

एक साधारण प्रोग्राम जो स्ट्रिंगरफर्गर और स्ट्रिंगबर्ल के बीच के अंतर को दर्शाता है:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}

4

StringBuffer को वर्ण स्ट्रिंग को संग्रहीत करने के लिए उपयोग किया जाता है जिसे परिवर्तित किया जाएगा (स्ट्रिंग ऑब्जेक्ट्स को बदला नहीं जा सकता)। यह स्वचालित रूप से आवश्यकतानुसार फैलता है। संबंधित कक्षाएं: स्ट्रिंग, चारसेंसेंस।

StringBuilder जावा 5 में जोड़ा गया था। यह StringBuffer को छोड़कर सभी मामलों में समान है, सिवाय इसके कि यह सिंक्रनाइज़ नहीं है, जिसका अर्थ है कि यदि एक ही समय में कई थ्रेड इसे एक्सेस कर रहे हैं, तो परेशानी हो सकती है। एकल-थ्रेडेड प्रोग्राम के लिए, सबसे आम मामला, सिंक्रनाइज़ेशन के ओवरहेड से बचने के लिए स्ट्रिंगबर्ल बहुत थोड़ा तेज होता है।


4
जावा में एकल-थ्रेडेड प्रोग्राम सबसे आम मामला नहीं है, लेकिन StringBuilderआमतौर पर एक विधि के लिए स्थानीय होते हैं, जहां वे केवल एक धागे के लिए दिखाई देते हैं।
फिन

4

StringBufferसिंक्रनाइज़ है, लेकिन StringBuilderनहीं है। नतीजतन, StringBuilderकी तुलना में तेज है StringBuffer


4

StringBuffer म्यूट है। यह लंबाई और सामग्री के संदर्भ में बदल सकता है। स्ट्रिंगबफर्स ​​थ्रेड-सुरक्षित होते हैं, जिसका अर्थ है कि उनके पास एक्सेस को नियंत्रित करने के लिए सिंक्रनाइज़ किए गए तरीके हैं ताकि एक बार में केवल एक थ्रेड स्ट्रिंग स्ट्रिंग ऑब्जेक्ट के सिंक्रनाइज़ किए गए कोड तक पहुंच सके। इस प्रकार, StringBuffer ऑब्जेक्ट्स आमतौर पर एक बहु-थ्रेडेड वातावरण में उपयोग करने के लिए सुरक्षित होते हैं जहाँ एक ही समय पर एक ही StringBuffer ऑब्जेक्ट तक पहुँचने के लिए कई थ्रेड्स प्रयास कर सकते हैं।

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


4

StringBuffer:

  • अनेक परतदार
  • सिंक्रनाइज़
  • StringBuilder की तुलना में धीमा

StringBuilder

  • एकल थ्रेड
  • नहीं-सिंक्रनाइज़
  • कभी भी स्ट्रिंग की तुलना में तेज़

2
अधिक सटीक, String c = a + bके बराबर है String c = new StringBuilder().append(a).append(b).toString(), इसलिए यह तेज नहीं है। यह केवल कि आप प्रत्येक स्ट्रिंग नियुक्ति के लिए एक नया बना, आप केवल एक हो सकता था, जबकि है ( String d = a + b; d = d + c;है String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();, जबकि StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();एक StringBuilder instanciation की बचत होगी)।
चोप

4

स्ट्रिंग-बिल्डर :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

स्ट्रिंग-बफर

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

जब भी संभव हो, स्ट्रिंग स्ट्रिंग का उपयोग करने की सिफारिश की जाती है क्योंकि यह स्ट्रिंगबफर की तुलना में तेज है। हालाँकि, यदि थ्रेड सुरक्षा आवश्यक है, तो सबसे अच्छा विकल्प StringBuffer ऑब्जेक्ट है।


यदि आपको थ्रेड सुरक्षा की आवश्यकता है, तो StringBuilder का उपयोग करना सबसे अच्छा विकल्प है क्योंकि StringBuffer केवल व्यक्तिगत संचालन के लिए थ्रेड सुरक्षित है। कई परिचालनों के लिए, आपको स्पष्ट लॉकिंग की आवश्यकता होती है।
पीटर लॉरी

4

बेहतर उपयोग के StringBuilderबाद से यह सिंक्रनाइज़ नहीं है और इसलिए बेहतर प्रदर्शन प्रदान करता है। पुराने की जगहStringBuilder एक ड्रॉप-इन हैStringBuffer


3
@ मर्क सच है, लेकिन ज्यादातर समय StringBu(ff|ild)erएक स्थानीय चर है जो केवल एक धागे द्वारा उपयोग किया जाता है।
गाबुजो

1
@MarkMcKenna: यहां तक ​​कि एक बहु-थ्रेडेड एप्लिकेशन में, किसी को अक्सर बाहरी लॉकिंग का उपयोग करना होगा, या इससे बचने के लिए अतिरिक्त काम करना होगा। उदाहरण के लिए, यदि दो धागे एक स्ट्रिंगर के लिए कई स्ट्रिंग्स वाले रिकॉर्ड को जोड़ना चाहते हैं, तो उन्हें जोड़े जाने वाले डेटा को एकत्र करना होगा और फिर इसे एक इकाई के रूप में जोड़ना होगा, भले ही यह तेज़ हो - अनुपस्थित थ्रेडिंग मुद्दे-- बस असतत परिशिष्ट संचालन के एक अनुक्रम प्रदर्शन करने के लिए।
सुपरकैट

3

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


3

के बीच कोई बुनियादी अंतर नहीं हैं , StringBuilderऔर StringBufferकेवल कुछ अंतर उनके बीच मौजूद हैं। में StringBufferतरीकों सिंक्रनाइज़ किए जाते हैं। इसका मतलब है कि एक समय में केवल एक धागा उन पर काम कर सकता है। यदि एक से अधिक धागे हैं तो दूसरे धागे को पहले एक के खत्म होने का इंतजार करना होगा और तीसरे को पहले और दूसरे के खत्म होने का इंतजार करना होगा। यह प्रक्रिया को बहुत धीमा कर देता है और इसलिए के मामले में प्रदर्शनStringBuffer कम है।

दूसरी ओर, StringBuilderसिंक्रनाइज़ नहीं है। इसका मतलब यह है कि एक StringBuilderही समय में एक ही ऑब्जेक्ट पर कई थ्रेड्स संचालित हो सकते हैं । इससे प्रक्रिया बहुत तेज हो जाती है और इसलिए प्रदर्शन StringBuilderअधिक होता है।


3

A Stringएक अपरिवर्तनीय वस्तु है जिसका अर्थ है कि मूल्य परिवर्तित नहीं किया जा सकता है जबकि StringBufferपरिवर्तनशील है।

StringBufferइसलिए सिंक्रनाइज़ है थ्रेड-सुरक्षित जबकि StringBuilderकेवल एकल पिरोया उदाहरण के लिए नहीं है और उपयुक्त है।


3
सिर्फ इसलिए कि StringBuffer में सिंक्रनाइज़ कोड है, जरूरी नहीं कि StringBuffer थ्रेडसेफ़ है। निम्नलिखित उदाहरण पर विचार करें: StringBuffer टेस्टिंगBuffer = "stackoverflow"; अब थ्रेड -1 टेस्टिंग बफ़र में "1" को जोड़ने की कोशिश कर रहा है, और थ्रेड -2 टेस्टिंग बफ़र के लिए "2" को जोड़ने की कोशिश कर रहा है। अब भले ही परिशिष्ट () विधि समकालिक है, यू यह सुनिश्चित नहीं किया जा सकता है कि क्या परीक्षण का मान बफ़र "स्टैकओवरफ़्लो 12" या "स्टैकओवरफ़्लो 21" होगा। दरअसल, ओरेकल द्वारा स्ट्रीबफायर के ऊपर स्ट्रिंगर का उपयोग करने की सलाह दी जाती है। मुझे आशा है कि इसने :)
बिमान त्रिपाठी

2

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


4
स्ट्रिंगबफ़र केवल थ्रेड सुरक्षित है यदि आप उस पर सिर्फ एक ऑपरेशन करते हैं। मैं इसे कई थ्रेड में उपयोग करने की अनुशंसा नहीं करूंगा क्योंकि यह सही होना बहुत कठिन है।
पीटर लॉरी

@PeterLawrey आपका क्या मतलब है? :-)
तमाड़ लैंग

1
@ b16db0 मेरा मतलब है कि StringBuffer के अधिकांश उपयोग थ्रेड सुरक्षित नहीं हैं क्योंकि वे बाहरी सिंक्रनाइज़ेशन के बिना इसे कई कॉल करते हैं, जिससे कक्षा व्यर्थ हो जाती है।
पीटर लॉरी

@PeterLawrey आह यह StringBuffer की तरह है अभी भी एक सिंक्रनाइज़ वातावरण की आवश्यकता है।
तमाड़ लैंग

2

के StringBufferऔर गैर-सिंक्रनाइज़ किए गए परिशिष्ट विधि के समन्वित परिशिष्ट विधि के आंतरिक की जाँच करेंStringBuilder

स्ट्रिंगर :

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

स्ट्रिंगबर्स्ट :

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

चूंकि एपेंड है synchronized, मल्टी-थ्रेडिंग परिदृश्य StringBufferकी तुलना में प्रदर्शन ओवरहेड StrinbBuilderहै। जब तक आप कई थ्रेड्स के बीच बफर साझा नहीं कर रहे हैं, तब तक उपयोग करें StringBuilder, जो synchronizedएपेंड विधियों में अनुपस्थिति के कारण तेज है ।


1

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

कोड :

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

मुझे विचारधारा पर निष्पादित करें

परिणाम :

एक पाठ जोड़ने के लिए 100000 पुनरावृत्ति

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

एक पाठ जोड़ने के लिए 10000 पुनरावृत्ति

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms

1
  • StringBuffer धागा सुरक्षित है लेकिन StringBuilder धागा सुरक्षित नहीं है।
  • StringBuilder StringBuffer की तुलना में तेज़ है।
  • StringBuffer सिंक्रनाइज़ है, जबकि StringBuilder सिंक्रनाइज़ नहीं है।

1

StringBuffer सिंक्रनाइज़ और थ्रेड सुरक्षित है, StringBuilder सिंक्रनाइज़ और तेज़ नहीं है।


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