30

Suppose I have an expression in Java such as:

String s = "abc" + methodReturningAString() + "ghi" + 
                anotherMethodReturningAString() + "omn" + "blablabla";

What's the behaviour of the Java's default JDK compiler? Does it just makes the five concatenations or there is a smart performance trick done?

Kip
  • 107,154
  • 87
  • 232
  • 265
Guilherme
  • 551
  • 4
  • 16

1 Answers1

40

It generates the equivalent of:

String s = new StringBuilder("abc")
           .append(methodReturningAString())
           .append("ghi")
           .append(anotherMethodReturningAString())
           .append("omn")
           .append("blablabla")
           .toString();

It is smart enough to pre-concatenate static strings (i.e. the "omn" + "blablabla"). You could call the use of StringBuilder a "performance trick" if you want. It is definitely better for performance than doing five concatenations resulting in four unnecessary temporary strings. Also, use of StringBuilder was a performance improvement in (I think) Java 5; prior to that, StringBuffer was used.

Edit: as pointed out in the comments, static strings are only pre-concatenated if they are at the beginning of the concatenation. Doing otherwise would break order-of-operations (although in this case I think Sun could justify it). So given this:

String s = "abc" + "def" + foo() + "uvw" + "xyz";

it would be compiled like this:

String s = new StringBuilder("abcdef")
           .append(foo())
           .append("uvw")
           .append("xyz")
           .toString();
Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Kip
  • 107,154
  • 87
  • 232
  • 265
  • +1. I saw the StringBuilder and was all set to post a clarification until I got to the bottom and found you'd already taken care of it. – Michael Myers Aug 18 '09 at 21:26
  • yep, i couldn't remember which one was correct, had to look it up after my initial revision – Kip Aug 18 '09 at 21:29
  • Actually, I was referring to the concatenation of string literals. At first glance, I thought you'd used a `.append` for each string. – Michael Myers Aug 18 '09 at 21:31
  • that's the second time on SO today that i misread someone's comment and responded to it... i must be getting old or something – Kip Aug 18 '09 at 21:35
  • 1
    @Kip: Not to be contrary, but I compiled the code with Sun's javac 1.6.0_15 and ran the .class through jad (and javap) and it actually compiled to: `String s = (new StringBuilder()). append("abc"). append(methodReturningAString()). append("ghi"). append(anotherMethodReturningAString()). append("omn"). append("blablabla"). toString();` It looks like the Sun compiler isn't smart enough to pre-concatenate static strings in this case. – Grant Wagner Aug 18 '09 at 21:38
  • 1
    @Kip: I compiled the same code using the compiler built into IBM RAD (based on Eclipse) and it compiled to: `String s = (new StringBuilder("abc")). append(methodReturningAString()). append("ghi"). append(anotherMethodReturningAString()). append("omn"). append("blablabla"). toString();` which still misses the literal string optimization, but at least creates the `StringBuilder` with the first `append()`able String. – Grant Wagner Aug 18 '09 at 21:42
  • 3
    It's not about being smart or not. The Java language specification has very specific rules about the order of evaluation, namely that it must be left-to-right when the operators are all of the same precedence. So, although "foo" + "bar" + baz does become new StringBuilder("foobar").append(baz), foo + "bar" + "baz" cannot be compiled into new StringBuilder().append(foo).append("barbaz") without breaking the order-of-evaluation rule. – C. K. Young Aug 18 '09 at 21:47
  • @Chris Jester-Young: @Grant Wagner: I've updated the answer with your feedback. At one point I'm pretty sure it used to create the StringBuilder object with the default (no-param) constructor, but I guess it doesn't any more – Kip Aug 18 '09 at 22:12
  • @Chris, that is true, but it can also be shown pre-compile that the order of evaluation does not change the result, so the optimization would be allowable. – Sam Harwell Aug 18 '09 at 22:15