Wednesday, February 28, 2007

StringBuilder vs. StringBuffer and the Java compiler

Since Java 5, a non-synchronized sibling to the popular StringBuffer class exists - StringBuilder. It's API compatible, and migration can be done with search-and-replace. StringBuilder is not thread-safe, but that's rarely a problem. A popular myth among Java developers is that this:

String comma = ", ";
String slow = "Hello" + comma + " world!";

is slower than this:

String comma = ", ";
String fast = new StringBuffer().append("Hello").append(comma).append("world!").toString();

The fact is that the Java compiler automatically converts the first line to the equivalent of the second, resulting in the same bytecode. That is, until Java 5, when the compiler instead selects StringBuilder.

The twist here is that if you're using Java 5 and a library that's very heavy on string handling (contcatenation) which is compatible with Java < 5, it might be a good idea to recompile it with the -target 1.5 parameter to convert all string concatenations to use StringBuilder. Of course, you should also replace any explicit usage of StringBuffer with StringBuilder.

I figured this out while profiling an application using Freemarker, which has a standard distribution that's compatible with Java 1.2.

No comments: