स्ट्रिंग संघनन: कॉनकट () बनाम "+" ऑपरेटर


499

स्ट्रिंग ए और बी मानकर:

a += b
a = a.concat(b)

हुड के तहत, वे एक ही बात कर रहे हैं?

यहाँ संदर्भ के रूप में समवर्ती विघटित है। मैं +ऑपरेटर को विघटित करने में सक्षम होना चाहता हूं और यह देखने के लिए कि वह क्या करता है।

public String concat(String s) {

    int i = s.length();
    if (i == 0) {
        return this;
    }
    else {
        char ac[] = new char[count + i];
        getChars(0, count, ac, 0);
        s.getChars(0, i, ac, count);
        return new String(0, count + i, ac);
    }
}


3
मुझे यकीन नहीं है कि +विघटित हो सकता है।
गेलन नारे

1
जावा क्लास फ़ाइल को डिसेबल करने के लिए javap का उपयोग करें ।
हॉट लिप्स

'अपरिवर्तनीयता' के कारण आपको संभवतः उपयोग करना चाहिए StringBufferया StringBuilder- (इस प्रकार तेजी से असुरक्षित धागा, इसके बजाय
उज्जवल सिंह

जवाबों:


560

नहीं, बिलकुल नहीं।

सबसे पहले, शब्दार्थ में थोड़ा अंतर है। यदि aहै null, तो a.concat(b)फेंकता है NullPointerExceptionलेकिन a+=bमूल मान को मान लेगा aजैसे कि वह था null। इसके अलावा, concat()विधि केवल Stringमूल्यों को स्वीकार करती है जबकि +ऑपरेटर चुपचाप तर्क को स्ट्रिंग में बदल देगा ( toString()ऑब्जेक्ट के लिए विधि का उपयोग करके )। इसलिए concat()जो इसे स्वीकार करता है, वह विधि अधिक सख्त है।

हुड के नीचे देखने के लिए, एक साधारण वर्ग के साथ लिखें a += b;

public class Concat {
    String cat(String a, String b) {
        a += b;
        return a;
    }
}

अब javap -c(सूर्य JDK में शामिल) के साथ जुदा । आपको एक सूची देखनी चाहिए जिसमें शामिल हैं:

java.lang.String cat(java.lang.String, java.lang.String);
  Code:
   0:   new     #2; //class java/lang/StringBuilder
   3:   dup
   4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   7:   aload_1
   8:   invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   11:  aload_2
   12:  invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   15:  invokevirtual   #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/    String;
   18:  astore_1
   19:  aload_1
   20:  areturn

तो, a += bके बराबर है

a = new StringBuilder()
    .append(a)
    .append(b)
    .toString();

concatविधि तेजी से होना चाहिए। हालांकि, अधिक स्ट्रिंग्स के साथ StringBuilderविधि जीत जाती है, कम से कम प्रदर्शन के मामले में।

के स्रोत कोड Stringऔर StringBuilder(और उसके पैकेज-निजी आधार वर्ग) सूर्य JDK के src.zip में उपलब्ध है। आप देख सकते हैं कि आप एक चार सरणी बना रहे हैं (आवश्यकतानुसार आकार) और फिर अंतिम बनाते समय इसे फेंक दें String। व्यवहार में स्मृति आवंटन आश्चर्यजनक रूप से तेज है।

अपडेट: पावेल एडम्सकी नोट्स के अनुसार, हाल के हॉटस्पॉट में प्रदर्शन बदल गया है। javacअभी भी बिल्कुल उसी कोड का उत्पादन करता है, लेकिन बायटेकोड कंपाइलर धोखा देता है। सरल परीक्षण पूरी तरह से विफल रहता है क्योंकि कोड के पूरे शरीर को फेंक दिया जाता है। सममिंग System.identityHashCode(नहीं String.hashCode) से पता चलता है कि StringBufferकोड में थोड़ा फायदा है। अगला अद्यतन जारी होने पर, या यदि आप किसी भिन्न JVM का उपयोग करते हैं, तो परिवर्तन के अधीन। से @lukaseder , हॉटस्पॉट JVM intrinsics की एक सूची


4
@ हाइपरलिंक आप javap -cएक संकलित वर्ग पर कोड का उपयोग करके देख सकते हैं जो इसका उपयोग करता है। (ओह, जैसा कि उत्तर में है। आपको बस
बायटेकोड डिस्सैम्प की

1
आप व्यक्तिगत बाइटकोड को समझने के लिए जेवीएम कल्पना से परामर्श कर सकते हैं । वह सामग्री जिसे आप संदर्भित करना चाहते हैं, अध्याय 6 में है। थोड़ा अस्पष्ट, लेकिन आप इसे आसानी से प्राप्त कर सकते हैं।
हॉट लिक्स

1
मुझे आश्चर्य है कि StringBuilderदो तारों को जोड़ते समय भी जावा कंपाइलर का उपयोग क्यों किया जाता है? यदि Stringचार स्ट्रिंग तक समाप्‍त करने के लिए स्थैतिक विधियाँ शामिल हैं, या String[]कोड में सभी तार, दो ऑब्जेक्ट एलोकेशन (परिणाम Stringऔर इसके बैकिंग char[], न ही एक निरर्थक), और तीन आबंटन के साथ किसी भी संख्या में स्ट्रिंग्स के साथ चार तार तक संलग्न हो सकते हैं ( String[], परिणाम String, और समर्थन char[], केवल पहले से किया जा रहा अनावश्यक के साथ)। जैसा कि यह है, का उपयोग StringBuilderकरना सबसे अच्छा चार आवंटन की आवश्यकता होगी, और हर चरित्र को दो बार कॉपी करने की आवश्यकता होगी।
20 अक्टूबर को सुपरकैट

वह अभिव्यक्ति, ए + बी। क्या इसका मतलब यह नहीं है: a = a + b?
सबसे आदरणीय सर

3
जब से यह उत्तर बनाया गया था तब से चीजें बदल गई हैं। कृपया मेरे उत्तर को पढ़ें।
पावेल अदाम्सकी

90

नियाज़ सही है, लेकिन यह भी ध्यान देने योग्य है कि विशेष + ऑपरेटर को जावा कंपाइलर द्वारा कुछ और अधिक कुशल में परिवर्तित किया जा सकता है। जावा में एक StringBuilder वर्ग है जो एक गैर-थ्रेड-सुरक्षित, म्यूटेबल स्ट्रिंग का प्रतिनिधित्व करता है। स्ट्रिंग संघनन का एक गुच्छा प्रदर्शन करते समय, जावा कंपाइलर चुपचाप धर्मान्तरित होता है

String a = b + c + d;

में

String a = new StringBuilder(b).append(c).append(d).toString();

जो बड़े तार के लिए काफी अधिक कुशल है। जहां तक ​​मुझे पता है, यह तब नहीं होता है जब आप कॉन्कैट विधि का उपयोग करते हैं।

हालाँकि, कॉनराट विधि अधिक कुशल है जब किसी मौजूदा स्ट्रिंग पर एक खाली स्ट्रिंग को सम्‍मिलित किया जाता है। इस मामले में, JVM को एक नई स्ट्रिंग ऑब्जेक्ट बनाने की आवश्यकता नहीं है और बस मौजूदा एक को वापस कर सकता है। इसकी पुष्टि करने के लिए कॉन्कैट डॉक्यूमेंटेशन देखें ।

इसलिए यदि आप दक्षता के बारे में सुपर-चिंतित हैं तो आपको संभवतः-खाली स्ट्रिंग्स को समतल करते समय कॉनकैट विधि का उपयोग करना चाहिए, और + अन्यथा का उपयोग करना चाहिए। हालाँकि, प्रदर्शन अंतर नगण्य होना चाहिए और आपको शायद इस बारे में कभी चिंता नहीं करनी चाहिए।


कॉनटैक्ट इन्फैक्ट ऐसा नहीं करता है। मैंने अपने पोस्ट को
कॉन्कैट

10
यह करता है। अपने संक्षिप्त कोड की पहली पंक्तियाँ देखें। समवर्ती के साथ समस्या यह है कि यह हमेशा एक नया स्ट्रिंग उत्पन्न करता है ()
Marcio Aguiar

2
@MarcioAguiar: शायद आपका मतलब है कि + हमेशा एक नया उत्पन्न करता है String- जैसा कि आप कहते हैं, concatएक अपवाद है जब आप एक खाली करते हैं String
ब्लिसोरब्लेड

45

मैंने @marcio के समान परीक्षण चलाया लेकिन इसके बजाय निम्नलिखित लूप के साथ:

String c = a;
for (long i = 0; i < 100000L; i++) {
    c = c.concat(b); // make sure javac cannot skip the loop
    // using c += b for the alternative
}

बस अच्छे उपाय के लिए, मैं भी फेंक दिया StringBuilder.append()। प्रत्येक परीक्षण 10 बार चलाया गया था, प्रत्येक रन के लिए 100k प्रतिनिधि थे। यहाँ परिणाम हैं:

  • StringBuilderजीतता है हाथ नीचे। अधिकांश रन के लिए घड़ी का समय 0 था, और सबसे लंबे समय तक 16ms लगे।
  • a += b प्रत्येक रन के लिए लगभग 40000ms (40s) लेता है।
  • concat प्रति रन केवल 10000ms (10s) की आवश्यकता है।

मैंने इन्टर्नल देखने के लिए कक्षा को विघटित नहीं किया है या इसे अभी तक प्रॉफ़ाइलर के माध्यम से चलाया है, लेकिन मुझे संदेह है कि मैं a += bसमय की नई वस्तुओं को बनाने StringBuilderऔर फिर उन्हें वापस परिवर्तित करने में बहुत समय बिताता हूँ String


4
ऑब्जेक्ट निर्माण समय वास्तव में मायने रखता है। इसीलिए कई स्थितियों में हम StringBuilder का उपयोग करने के बजाय सीधे StringBuilder का लाभ उठाते हैं।
कूलफैन

1
@coolcfan: जब +दो तारों के लिए उपयोग किया जाता है, तो क्या ऐसे कोई मामले हैं, जिनका उपयोग StringBuilderकरना बेहतर है String.valueOf(s1).concat(s2)? कोई भी विचार क्यों कंपाइलर उत्तरार्द्ध का उपयोग नहीं करेगा [या फिर उन valueOfमामलों में कॉल को छोड़ दें जहां s1गैर-अशक्त हो]?
सुपरकाट

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

25

यहां अधिकांश उत्तर 2008 से हैं। ऐसा लगता है कि समय के साथ चीजें बदल गई हैं। जेएमएच के साथ किए गए मेरे नवीनतम बेंचमार्क बताते हैं कि जावा 8 +की तुलना में लगभग दो गुना तेज है concat

मेरा बेंचमार्क:

@Warmup(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
public class StringConcatenation {

    @org.openjdk.jmh.annotations.State(Scope.Thread)
    public static class State2 {
        public String a = "abc";
        public String b = "xyz";
    }

    @org.openjdk.jmh.annotations.State(Scope.Thread)
    public static class State3 {
        public String a = "abc";
        public String b = "xyz";
        public String c = "123";
    }


    @org.openjdk.jmh.annotations.State(Scope.Thread)
    public static class State4 {
        public String a = "abc";
        public String b = "xyz";
        public String c = "123";
        public String d = "!@#";
    }

    @Benchmark
    public void plus_2(State2 state, Blackhole blackhole) {
        blackhole.consume(state.a+state.b);
    }

    @Benchmark
    public void plus_3(State3 state, Blackhole blackhole) {
        blackhole.consume(state.a+state.b+state.c);
    }

    @Benchmark
    public void plus_4(State4 state, Blackhole blackhole) {
        blackhole.consume(state.a+state.b+state.c+state.d);
    }

    @Benchmark
    public void stringbuilder_2(State2 state, Blackhole blackhole) {
        blackhole.consume(new StringBuilder().append(state.a).append(state.b).toString());
    }

    @Benchmark
    public void stringbuilder_3(State3 state, Blackhole blackhole) {
        blackhole.consume(new StringBuilder().append(state.a).append(state.b).append(state.c).toString());
    }

    @Benchmark
    public void stringbuilder_4(State4 state, Blackhole blackhole) {
        blackhole.consume(new StringBuilder().append(state.a).append(state.b).append(state.c).append(state.d).toString());
    }

    @Benchmark
    public void concat_2(State2 state, Blackhole blackhole) {
        blackhole.consume(state.a.concat(state.b));
    }

    @Benchmark
    public void concat_3(State3 state, Blackhole blackhole) {
        blackhole.consume(state.a.concat(state.b.concat(state.c)));
    }


    @Benchmark
    public void concat_4(State4 state, Blackhole blackhole) {
        blackhole.consume(state.a.concat(state.b.concat(state.c.concat(state.d))));
    }
}

परिणाम:

Benchmark                             Mode  Cnt         Score         Error  Units
StringConcatenation.concat_2         thrpt   50  24908871.258 ± 1011269.986  ops/s
StringConcatenation.concat_3         thrpt   50  14228193.918 ±  466892.616  ops/s
StringConcatenation.concat_4         thrpt   50   9845069.776 ±  350532.591  ops/s
StringConcatenation.plus_2           thrpt   50  38999662.292 ± 8107397.316  ops/s
StringConcatenation.plus_3           thrpt   50  34985722.222 ± 5442660.250  ops/s
StringConcatenation.plus_4           thrpt   50  31910376.337 ± 2861001.162  ops/s
StringConcatenation.stringbuilder_2  thrpt   50  40472888.230 ± 9011210.632  ops/s
StringConcatenation.stringbuilder_3  thrpt   50  33902151.616 ± 5449026.680  ops/s
StringConcatenation.stringbuilder_4  thrpt   50  29220479.267 ± 3435315.681  ops/s

मुझे आश्चर्य है कि क्यों जावा Stringने स्थैतिक फ़ंक्शन को शामिल करने के लिए स्ट्रिंग के तत्वों को सम्मिलित करके कभी नहीं बनाया String[]+इस तरह के एक समारोह का उपयोग करते हुए 8 तारों का उपयोग करने के लिए निर्माण और बाद में छोड़ने की आवश्यकता होती है String[8], लेकिन यह एकमात्र ऐसी वस्तु होगी जिसे StringBuilderत्यागने की आवश्यकता होगी , जबकि उपयोग करने के लिए निर्माण और त्यागने की आवश्यकता होगी StringBuilderऔर कम से कम एक char[]बैकिंग स्टोर की आवश्यकता होगी।
सुपरकैट

@supercat String.join()जावा 8 में कुछ स्थिर तरीकों को जोड़ा गया, क्योंकि java.util.StringJoinerकक्षा के आसपास त्वरित वाक्यविन्यास आवरण ।
तिवारी

@TiStrga: क्या +ऐसे कार्यों का उपयोग करने के लिए बदले की हैंडलिंग है ?
सुपरकैट

@supercat बाइनरी बैकवर्ड संगतता को तोड़ देगा, इसलिए नहीं। यह अपने "क्यों स्ट्रिंग एक स्थिर समारोह शामिल कभी नहीं" टिप्पणी के जवाब में केवल था: अब वहाँ है इस तरह के एक समारोह। आपके प्रस्ताव के बाकी ( +इसे उपयोग करने के लिए refactoring ) की तुलना में जावा देवों को बदलने के लिए तैयार, दुख की बात की तुलना में अधिक की आवश्यकता होगी।
टीआई स्ट्रगा

@TiStrga: क्या किसी भी तरह से जावा बाइटकोड फ़ाइल यह संकेत दे सकती है कि "यदि फ़ंक्शन एक्स उपलब्ध है, तो उसे कॉल करें, अन्यथा कुछ और करें" एक तरह से जिसे कक्षा को लोड करने की प्रक्रिया में हल किया जा सकता है? एक स्थिर विधि के साथ कोड बनाना जो या तो जावा के स्थैतिक विधि से श्रृंखला बना सकता है या फिर एक स्ट्रिंगर का उपयोग कर सकता है यदि यह उपलब्ध नहीं है तो इष्टतम समाधान प्रतीत होगा।
सुपरकैट

22

टॉम ठीक से वर्णन करता है कि + ऑपरेटर क्या करता है। यह एक अस्थायी बनाता है StringBuilder, भागों को जोड़ता है, और के साथ खत्म होता है toString()

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

@marcio: आपने एक माइक्रो-बेंचमार्क बनाया है ; आधुनिक जेवीएम के साथ यह प्रोफाइल कोड का एक वैध तरीका नहीं है।

रन-टाइम ऑप्टिमाइज़ेशन मामलों का कारण यह है कि कोड के इन अंतरों में से कई - यहां तक ​​कि ऑब्जेक्ट-क्रिएशन सहित - हॉटस्पॉट के जाने के बाद पूरी तरह से अलग हैं। सुनिश्चित करने के लिए पता करने का एकमात्र तरीका सीटू में आपके कोड की रूपरेखा है ।

अंत में, ये सभी विधियां वास्तव में अविश्वसनीय रूप से तेज हैं। यह समय से पहले अनुकूलन का मामला हो सकता है। यदि आपके पास ऐसा कोड है जो बहुत सारे तार जोड़ता है, तो अधिकतम गति प्राप्त करने का तरीका संभवत: कुछ भी नहीं है जो आप चुनते हैं और इसके बजाय आप जो एल्गोरिथ्म का उपयोग कर रहे हैं, उसके साथ क्या करना है!


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

21

कैसे कुछ सरल परीक्षण के बारे में? नीचे दिए गए कोड का उपयोग करें:

long start = System.currentTimeMillis();

String a = "a";

String b = "b";

for (int i = 0; i < 10000000; i++) { //ten million times
     String c = a.concat(b);
}

long end = System.currentTimeMillis();

System.out.println(end - start);
  • "a + b"संस्करण में मार डाला 2500ms
  • a.concat(b)में मार डाला 1200ms

कई बार परीक्षण किया गया। concat()संस्करण निष्पादन औसतन आधे समय के लिए ले लिया।

इस परिणाम ने मुझे आश्चर्यचकित कर दिया क्योंकि concat()विधि हमेशा एक नया स्ट्रिंग बनाती है (यह " new String(result)" लौटाता है । यह सर्वविदित है कि:

String a = new String("a") // more than 20 times slower than String a = "a"

कंपाइलर "a + b" कोड में स्ट्रिंग निर्माण को अनुकूलित करने में सक्षम क्यों नहीं था, यह जानने के बाद कि हमेशा एक ही स्ट्रिंग में परिणाम होता है? यह एक नए स्ट्रिंग निर्माण से बच सकता है। यदि आप उपरोक्त कथन को नहीं मानते हैं, तो अपने स्वयं के लिए परीक्षण करें।


मैंने java jdk1.8.0_241 पर आपके कोड का परीक्षण किया, मेरे लिए "a + b" कोड अनुकूलित परिणाम दे रहा है। कॉन्कैट के साथ (): 203ms और "+" के साथ: 113ms । मुझे लगता है कि पिछली रिलीज में यह अनुकूलित नहीं था।
अक्की

6

मूल रूप से, + और concatविधि के बीच दो महत्वपूर्ण अंतर हैं ।

  1. यदि आप कॉन्कैट विधि का उपयोग कर रहे हैं, तो आप केवल स्ट्रिंग को सम्‍मिलित करने में सक्षम होंगे जबकि + ऑपरेटर के मामले में , आप किसी भी डेटा प्रकार के साथ स्ट्रिंग को भी सम्‍मिलित कर सकते हैं।

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

    String s = 10 + "Hello";

    इस मामले में, आउटपुट 10Hello होना चाहिए ।

    String s = "I";
    String s1 = s.concat("am").concat("good").concat("boy");
    System.out.println(s1);

    उपरोक्त मामले में आपको दो तार अनिवार्य करने होंगे।

  2. दूसरा और मुख्य अंतर + और अवतल के बीच है:

    केस 1: मान लीजिए कि मैं इस तरह से कॉनरेट ऑपरेटर के साथ एक ही तार को समेटता हूं

    String s="I";
    String s1=s.concat("am").concat("good").concat("boy");
    System.out.println(s1);

    इस मामले में पूल में बनाई गई कुल वस्तुओं की संख्या 7 इस प्रकार है:

    I
    am
    good
    boy
    Iam
    Iamgood
    Iamgoodboy

    केस 2:

    अब मैं + ऑपरेटर के माध्यम से समान स्ट्रिंग्स को समाप्‍त करने जा रहा हूं

    String s="I"+"am"+"good"+"boy";
    System.out.println(s);

    उपरोक्त मामले में बनाई गई वस्तुओं की कुल संख्या केवल 5 हैं।

    वास्तव में जब हम स्ट्रिंग्स को + ऑपरेटर के माध्यम से समाप्‍त करते हैं तो यह एक स्ट्रिंगरबफ़र वर्ग को उसी कार्य को करने के लिए बनाए रखता है: -

    StringBuffer sb = new StringBuffer("I");
    sb.append("am");
    sb.append("good");
    sb.append("boy");
    System.out.println(sb);

    इस तरह यह केवल पाँच वस्तुओं का निर्माण करेगा।

तो लोग इन के बीच बुनियादी मतभेद हैं + और concat विधि। का आनंद लें :)


मेरे प्रिय, आप अच्छी तरह जानते हैं कि किसी भी स्ट्रिंग शाब्दिक को एक स्ट्रिंग ऑब्जेक्ट के रूप में माना जाता है जो स्ट्रिंग पूल में संग्रहीत होता है। इस मामले में हमारे पास 4 स्ट्रिंग साहित्यिक हैं। जाहिर है कम से कम 4 ऑब्जेक्ट पूल में बनाए जाने चाहिए।
दीपक शर्मा

1
मुझे ऐसा नहीं लगता: String s="I"+"am"+"good"+"boy"; String s2 = "go".concat("od"); System.out.println(s2 == s2.intern());प्रिंट true, जिसका अर्थ है "good"कि कॉल करने से पहले स्ट्रिंग पूल में नहीं थाintern()
फैबियन

मैं केवल इस पंक्ति के बारे में बात कर रहा हूँ स्ट्रिंग s = "मैं" + "हूँ" + "अच्छा" + "लड़का"; इस स्थिति में सभी 4 स्ट्रिंग शाब्दिक एक पूल में रखे गए हैं। 4 वस्तुओं को पूल में बनाया जाना चाहिए।
दीपक शर्मा

4

पूर्णता के लिए, मैं यह जोड़ना चाहता था कि '+' ऑपरेटर की परिभाषा JLS SE8 15.18.1 में पाई जा सकती है :

यदि केवल एक ऑपरेंड एक्सप्रेशन टाइप स्ट्रिंग का है, तो दूसरे समय पर स्ट्रिंग कन्वर्जन (.15.1.11) दूसरे ऑपरेंड पर किया जाता है ताकि रन टाइम पर एक स्ट्रिंग का निर्माण किया जा सके।

स्ट्रिंग संघनन का परिणाम एक स्ट्रिंग ऑब्जेक्ट का संदर्भ है जो दो ऑपरेंड स्ट्रिंग्स का संयोजन है। बाएं हाथ के ऑपरेंड के चरित्र नए बनाए गए स्ट्रिंग में दाहिने हाथ के ऑपरेंड के पात्रों से पहले हैं।

स्ट्रिंग ऑब्जेक्ट नव निर्मित (.512.5) है जब तक कि अभिव्यक्ति एक स्थिर अभिव्यक्ति नहीं है (.215.28)।

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

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

आदिम प्रकारों के लिए, एक कार्यान्वयन एक आवरण प्रकार के निर्माण को सीधे एक आदिम प्रकार से एक स्ट्रिंग में परिवर्तित करके अनुकूलित कर सकता है।

इसलिए 'एक जावा संकलक स्ट्रिंगरबफ़र वर्ग या एक समान तकनीक को कम करने के लिए उपयोग कर सकता है' को देखते हुए, विभिन्न संकलक अलग-अलग बाइट-कोड का उत्पादन कर सकते हैं।


2

+ संचालक एक स्ट्रिंग और एक स्ट्रिंग, चार, पूर्णांक, डबल या नाव डेटा प्रकार मूल्य के बीच काम कर सकते हैं। यह सिर्फ संघनन से पहले अपने स्ट्रिंग प्रतिनिधित्व के मूल्य को परिवर्तित करता है।

concat ऑपरेटर केवल पर और तार के साथ किया जा सकता है। यदि वे मेल नहीं खाते हैं, तो यह डेटा प्रकार संगतता के लिए जाँच करता है और एक त्रुटि फेंकता है।

इसके अलावा, आपके द्वारा प्रदान किया गया कोड समान सामान करता है।


2

मुझे ऐसा नहीं लगता।

a.concat(b)स्ट्रिंग में लागू किया गया है और मुझे लगता है कि प्रारंभिक जावा मशीनों के बाद से कार्यान्वयन में बहुत बदलाव नहीं हुआ है। +आपरेशन कार्यान्वयन जावा संस्करण और संकलक पर निर्भर करता है। वर्तमान में ऑपरेशन को यथासंभव तेज करने के लिए +उपयोग StringBufferकिया जाता है। शायद भविष्य में, यह बदल जाएगा। +स्ट्रिंग्स पर जावा ऑपरेशन के पहले के संस्करणों में बहुत धीमी थी क्योंकि यह मध्यवर्ती परिणाम उत्पन्न करता था।

मुझे लगता है कि +=इसका उपयोग करके +और इसी तरह से अनुकूलित किया गया है।


7
"वर्तमान में" StringBuffer का उपयोग करके लागू किया गया है "झूठी यह StringBuilder है। StringBuffer StringBuilder का धागा है।
फ्रेडरिक मोरिन

1
यह जावा 1.5 से पहले स्ट्रिंगरबफ़र हुआ करता था, क्योंकि यही वह संस्करण था जब स्ट्रिंगबर्स्ट को पहली बार पेश किया गया था।
सीसीपीजेडा

0

+ का उपयोग करते समय, स्ट्रिंग की लंबाई बढ़ने के साथ गति कम हो जाती है, लेकिन जब कॉनैट का उपयोग करते हैं, तो गति अधिक स्थिर होती है, और सबसे अच्छा विकल्प स्ट्रिंगब्यूलर क्लास का उपयोग होता है जिसमें ऐसा करने के लिए स्थिर गति होती है।

मुझे लगता है कि आप समझ सकते हैं कि क्यों। लेकिन लंबे स्ट्रिंग्स बनाने के लिए पूरी तरह से सबसे अच्छा तरीका है स्ट्रिंगब्यूलर () और एपेंड () का उपयोग करना, या तो गति अस्वीकार्य होगी।


1
+ ऑपरेटर का उपयोग करना StringBuilder ( docs.oracle.com/javase/specs/jls/se8/html/… ) का उपयोग करने के बराबर है
ihebiheb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.