2

I am wondering if anyone could give me an answer as to which one of these statements would perform better in java using StringBuilder object:

Using

.append(string1 + string 2) 

vs

.append(string1).append(string2)
arshajii
  • 127,459
  • 24
  • 238
  • 287
  • 2
    I would go with the second option since the 1st one would most likely create an intermediate (unnecessary) string – Алексей Dec 19 '13 at 19:24
  • Related: http://stackoverflow.com/questions/65668/why-to-use-stringbuffer-in-java-instead-of-the-string-concatenation-operator – Joel Dec 19 '13 at 19:29
  • If both strings are compile-time constants, use `+`; the compiler will concatenate at compile-time. Otherwise, use two appends. – Ed Staub Dec 19 '13 at 19:44

4 Answers4

4

The second option will almost certainly be superior (assuming there is any noticeable performance difference at all). When you write something like

string1 + string2

it is internally translated to

new StringBuilder(string1).append(string2).toString()

i.e. a new StringBuilder is created to concatenate the strings. Your second variant circumvents this issue since it appends directly to the existing StringBuilder, avoiding the creation of a new one.

arshajii
  • 127,459
  • 24
  • 238
  • 287
1

We can take a look at the bytecode for each option:

public class Concat {
    private static String s1 = "foo";
    private static String s2 = "bar";

    public static String good() {
        StringBuilder b = new StringBuilder();
        b.append(s1).append(s2);
        return b.toString();
    }

    public static String bad() {
        StringBuilder b = new StringBuilder();
        b.append(s1 + s2);
        return b.toString();
    }
}

$javap -c Concat.class

 public static java.lang.String good();
    Code:
       0: new           #2                  // class java/lang/StringBuilder
       3: dup           
       4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
       7: astore_0      
       8: aload_0       
       9: getstatic     #4                  // Field s1:Ljava/lang/String;
      12: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: getstatic     #6                  // Field s2:Ljava/lang/String;
      18: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: pop           
      22: aload_0       
      23: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      26: areturn       

  public static java.lang.String bad();
    Code:
       0: new           #2                  // class java/lang/StringBuilder
       3: dup           
       4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
       7: astore_0      
       8: aload_0       
       9: new           #2                  // class java/lang/StringBuilder
      12: dup           
      13: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
      16: getstatic     #4                  // Field s1:Ljava/lang/String;
      19: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      22: getstatic     #6                  // Field s2:Ljava/lang/String;
      25: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      34: pop           
      35: aload_0       
      36: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

Your first option actually becomes append(new StringBuilder().append(s1).append(s2).toString()).

Jeffrey
  • 44,417
  • 8
  • 90
  • 141
0

The first one is quicker to type and in many situations easier to read.

The second one may perform marginally better (as per Jeffrey's bytecode and arshajii's explanation).

However, this kind string concatenation is very unlikely to be the bottleneck in your system! If performance is a problem, you need to profile. Compilers differ. And improving algorithms generally has much, much more impact than this kind of micro-optimization.

Don't optimize earlier than necessary! Really! It's so tempting and such a waste of time.

ᴇʟᴇvᴀтᴇ
  • 12,285
  • 4
  • 43
  • 66
0

It may be reasonably expected that a future improvement in the compiler will make both alternatives generate the same code.

Jonathan Rosenne
  • 2,159
  • 17
  • 27