5

How many memory locations will it take to have a string concatenation?

String myStringVariable = "Hello";

In following two statements :

String s = "ABC" + "Hello" + "DEF";

and

String s = "ABC";
s = s + "Hello";
s = s + "DEF";

and

String s = "ABC" + myStringVariable + "DEF";

Which will consume more memory? In which of the case StringBuilder is useful to the most?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Eldhose M Babu
  • 14,382
  • 8
  • 39
  • 44
  • The first one is definitely amenable to constant-folding. The second one should be as well. – millimoose Nov 28 '13 at 09:20
  • Correction: the second example will not, in fact, be constant-folded. (Also: did you HAVE to change the samples after you received answers?) – millimoose Nov 28 '13 at 09:33

6 Answers6

4

First statement will be converted by compiler into String s = "ABCDEF"; so there will be no concatination

Second statement will be converted by compiler into this code (or something like this)

    String s = "ABC";
    StringBuilder sb = new StringBuilder(s);
    sb.append("DEF");
    s = sb.toString();
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • what JVM Vendor/Version supports this resolution? Particularly the second one (obviously at least >=1.5)? – Yaneeve Nov 28 '13 at 09:30
  • First case behaviour is defined by JLS - compile time constant. Second >= 1.5 for sure since StringBuilder was introduced in 1.5 – Evgeniy Dorofeev Nov 28 '13 at 09:34
  • 1
    @Yaneeve: Before 1.5, `StringBuffer` was used the same way `StringBuilder` is used today. This feature exists since the very first version. – Holger Nov 28 '13 at 09:35
  • @Yaneeve I believe there was a version that, for the second OP's sample, would have created two `StringBuffer`s. However it's old enough to be irrelevant. Concatenation was always done using `StringBuilder` or `StringBuffer` I believe, there is no "native" concatenation operation in the JDK. (Although an alternative JDK is free to compile string concatenation to something else as long as it works.) – millimoose Nov 28 '13 at 09:35
  • OK, so the first case is defined by the JLS, but for the second, I gather, from your comments that it is hotspot's behavior, does any other vendor do it likewise? – Yaneeve Nov 28 '13 at 09:48
  • I cannot verify it but it is quite logical to use StringBuilder for concatination because it is faster than the other option - String.concat – Evgeniy Dorofeev Nov 28 '13 at 09:53
  • 1
    @Yaneeve: It’s the compiler, i.e. javac, creating the code using a `StringBuilder`. This has nothing to do with HotSpot. – Holger Nov 28 '13 at 10:22
  • @Yaneeve Are you really using a JVM from some other vendor than Oracle? If you are, you can verify it yourself. If you aren't, then why would you care? If you're curious you can still check yourself by compiling with each alternative JDK and decompiling with `javap`. – millimoose Nov 30 '13 at 20:51
  • 1
    It seems, the question has been edited after this answer has been written. The “second example”, to which this answer refers, does not exist anymore. The current second example is `String s = "ABC" + "Hello" + "DEF";`, which will be compiled to `String s = "ABCHelloDEF";`. – Holger Feb 13 '20 at 15:28
3

StringBuilder will be helpful in neither case, as written - the compiler will reuse the same StringBuilder instance when possible. It's marginally helpful when you're adding strings in a loop. (I say "marginally" because most of the time you're not really adding that many strings, nor are they that long. The difference will show up in microbenchmarks but your program isn't one, unless you're writing a templating engine or something like that.)

Creating garbage StringBuilders doesn't "waste memory" as much as cause GC pressure. A generational scavenger GC such as Java's is, in fact, designed to make creating lots of very short-lived garbage objects efficient. I wouldn't worry about it unless you're actually spending too much time in GC.

Copying the String contents into the StringBuilders repeatedly is also wasteful, but once again, unlikely to make a significant impact outside a loop.

millimoose
  • 39,073
  • 9
  • 82
  • 134
2
String s = "ABC" + "DEF";

That resolved at compile time and no StringBuilder used to concat.

and

String s = "ABC";
s = s + "DEF";   

In this case StringBuilder(string...).toString() to resolve the String at run time.

So you need to use StringBuilder, In your case it's negligible performance difference.

do not use much concatenation's with "+", cannot do much harm in lesser amount of concatenations. If you are dealing with larger amount prefer to use StringBuilder with append method.

You can see the difference if you are concatenating String's in Large extent with +, then go for StringBuilder append.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
2

I create class Main:

public class Main {
    public String foo() {
        String s = "ABC" + "DEF";
        return s;
    }
    public String foo1() {
        String s = "ABC";
        s = s + "DEF";
        return s;
    }
}

and decompile it:

public java.lang.String foo();
Signature: ()Ljava/lang/String;
Code:
   0: ldc           #2                  // String ABCDEF
   2: astore_1
   3: aload_1
   4: areturn

public java.lang.String foo1();
Signature: ()Ljava/lang/String;
Code:
   0: ldc           #3                  // String ABC
   2: astore_1
   3: new           #4                  // class java/lang/StringBuilder
   6: dup
   7: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
  10: aload_1
  11: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  14: ldc           #7                  // String DEF
  16: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  19: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  22: astore_1
  23: aload_1
  24: areturn

Method foo make concatenation string compile-time but method foo1 concatenate string at run-time and use StringBuilder.

First example use less memory.

I use Oracle JDK 1.7_45 with default properties.

Sergey Morozov
  • 4,528
  • 3
  • 25
  • 39
1

Which will consume more memory?

The java specification 15.8.1 String Concatenation Operator +:

The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

  • First statement,

     String s = "ABC" + "Hello" + "DEF";
    

    This expression is a compile-time constant expression. Will be done in one step. No object is created in run-time.

  • Second statement:

      String s = "ABC";
      s = s + "Hello";
      s = s + "DEF";
    

    this statement will create a new string containing "ABCHELLO". Third statement will create a new string containing "ABCHELLODEF". This string concatenation will happen using a StringBuilder.

  • Third statement

    String s = "ABC" + myStringVariable + "DEF";
    

    unlike the first statement, this statement Will create one new instance at run-time as it is not a compile-time constant expression.

But using StringBuilder for concatenating such three string won't result in performance gain, unless you are working with number of strings with which counting does matter.

Sage
  • 15,290
  • 3
  • 33
  • 38
0

StringBuilder is useful when you want to play with string. dynamically creating string by combining string. it will occupy in one object only.

if you use string every time it any concatenation will create new object in memory.

shreyansh jogi
  • 2,082
  • 12
  • 20