Java: String concat vs StringBuilder - optimised, so what should I do?

JavaStringAppendConcatenationStringbuilder

Java Problem Overview


In this answer, it says (implies) that String concatenation is optimised into StringBuilder operations anyway, so when I write my code, is there any reason to write StringBuilder code in the source? Note that my use case is different from the OP's question, as I am concatenating/appending hundreds-thousands of lines.

To make myself clearer: I am well-aware about the differences of each, it's just that I don't know if it's worth actually writing StringBuilder code because it's less readable and when its supposedly slower cousin, the String class, is converted automagically in the compilation process anyway.

Java Solutions


Solution 1 - Java

I think the use of StringBuilder vs + really depends on the context you are using it in.

Generally using JDK 1.6 and above the compiler will automatically join strings together using StringBuilder.

String one = "abc";
String two = "xyz";
String three = one + two;

This will compile String three as:

String three = new StringBuilder().append(one).append(two).toString();

This is quite helpful and saves us some runtime. However this process is not always optimal. Take for example:

String out = "";
for( int i = 0; i < 10000 ; i++ ) {
    out = out + i;
}
return out;

If we compile to bytecode and then decompile the bytecode generated we get something like:

String out = "";
for( int i = 0; i < 10000; i++ ) {
    out = new StringBuilder().append(out).append(i).toString();
}
return out;

The compiler has optimised the inner loop but certainly has not made the best possible optimisations. To improve our code we could use:

StringBuilder out = new StringBuilder();
for( int i = 0 ; i < 10000; i++ ) {
    out.append(i);
}
return out.toString();

Now this is more optimal than the compiler generated code, so there is definitely a need to write code using the StringBuilder/StringBuffer classes in cases where efficient code is needed. The current compilers are not great at dealing concatenating strings in loops, however this could change in the future.

You need to look carefully to see where you need to manually apply StringBuilder and try to use it where it will not reduce readability of your code too.

Note: I compiled code using JDK 1.6, and and decompiled the code using the javap program, which spits out byte code. It is fairly easy to interpret and is often a useful reference to look at when trying to optimise code. The compiler does change you code behind the scenes so it is always interesting to see what it does!

Solution 2 - Java

The key phrase in your question is "supposedly slower". You need to identify if this is indeed a bottleneck, and then see which is faster.

If you are about to write this code, but have not written it yet, then write whatever is clearer to you and then if necessay see if it is a bottleneck.

While it makes sense to use the code you consider more likey to be faster, if both are equally readable, actually taking time to find out which is faster when you don't have a need is a waste of time. Readability above performance until performance is unacceptable.

Solution 3 - Java

It depends on the case, but StringBuilder is thought to be a bit faster. If you are doing concatenation inside a loop then I would suggest you use StringBuilder.

Anyway, I would advise you to profile and benchmark your code (if you are doing such a massive append).

Be careful though: instances of StringBuilder are mutable and are not to be shared between threads (unless you really know what you are doing.) as opposed to String which are immutable.

Solution 4 - Java

I might've misunderstood your question, but StringBuilder is faster when appending Strings. So, yes, if you are appending "hundreds-thousands of lines", you definitely should use StringBuilder (or StringBuffer if you are running a multithreaded app).

(More thorough answer in comments)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSoyuzView Question on Stackoverflow
Solution 1 - JavaTom CammannView Answer on Stackoverflow
Solution 2 - JavajmorenoView Answer on Stackoverflow
Solution 3 - JavabssstudioView Answer on Stackoverflow
Solution 4 - Javauser1348997View Answer on Stackoverflow