31

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?

1 Answer 1

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();
Sign up to request clarification or add additional context in comments.

9 Comments

+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.
yep, i couldn't remember which one was correct, had to look it up after my initial revision
@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.
@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.
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.