String theory – StringBuilder vs. String + String in the great speed debate!

I had a debate a while back about the efficiency of string concatenation using the ‘+’ operator.
This recently came around again  on a Java forum that I had posted on.

I’d seen some code that had concatenated several strings using StringBuffer.

The code was pre-JDK 5 and we were re-using bits of it for a project I was on. Since StringBuffer wasn’t needed
as no synchronization was being performed, the first refactoring prior to migration was changing StringBuffer to StringBuilder.

What struck me as odd was that the (now StringBuilder) object wasn’t being used inside of any sort of loop structure or any other programmatic
structure that would warrant the creation of a StringBuilder object.

The code actually looked similar to this:

public String message1(String value1, String value2) {
     StringBuilder messageBuilder = new StringBuilder();
     messageBuilder.append("Value ")
     .append(value1)
     .append(" is greater than ")
     .append(value2);
     return messageBuilder.toString();
}

Since I thought this to be a bit overkill, I refactored the code to now look similar to this:

public String message1(String value1, String value2) {
     return "Value " + value1 + " is greater than " + value2;
}

Let The Debate Ensue!

This started quite the performance debate. Many of my colleagues on the project were under the impression that StringBuilder concatenation
is ALWAYS faster than String concatenation using the + operator. Many of them also thought it bad practice to use anything but StringBuilder
when concatenating multiple Strings and had gotten in the habit of using Builder’s for all concatenation in all code to “speed things up”.

I will agree that there are certain instances where using StringBuilder performs better than using Strings and +. Loop structures are one such
case. Appending to a String is much faster inside a loop structure with a StringBuilder (provided the builder was created outside the loop
structure where the appending occurs) than using + or +=.

But StringBuilder isn’t a one-stop shop for String performance enhancement by any means.

Used in the above code example it does 2 things:
1. Makes the code uglier. Granted, this is my own opinion and I’m sure that some might disagree. I personally feel
that the chained calls to append() are ugly when used like this. I think that in cases like this, using + to concatenate
Strings is less intrusive and makes the code easier to read.

2. IT ACTUALLY HURTS PERFORMANCE! – This is was the core of the above debate. Many had taken the StringBuilder for performance
pattern as gospel and had never looked into when this is applicable and when it isn’t.

If you don’t believe me, try a simple test of timing the calls of the above methods for yourself ( I recommend using
System.nanoTime() instead of System.currentTimeMillis() ).

If your a bit more curious – take a look at the actual bytecode that is generated from each of the methods using a tool like ASM!
This is where things really get interesting!

2 Comments

Filed under Java

2 responses to “String theory – StringBuilder vs. String + String in the great speed debate!

  1. I’m honestly not going to bother running any tests on this. Here’s my opinion: you’re writing in Java, if people are that worried about performance to nit-pick the two cases you present, then you shouldn’t be using Java. Now, that’s harsh and the statement can easily fall apart if you look at it literally. But all things considered, this situation is just plain silly. The exact case you’re pointing out is almost a no-brainer in favor of + concatenation because the overhead of creating a StringBuilder object and manipulating it for the sole purpose of returning a String object isn’t worth it. As you said yourself, it’s not being concatenated within a loosely bound loop structure, so who cares?

    You want to use StringBuilder when you either can’t guarantee the number of concatenations, or you can, but the number is pretty large. In your example though, it’s THREE operations. Sometimes developer performance is more important than runtime performance. You’d have to be crazy to tell me StringBuilder is easier to write than good ol’ + concat syntax. Developer performance is why the Java language even exists; be glad you’re not sprintf()’ing every time you want to concat strings.

    Purely as an exercise of Computer Science though, it’s an interesting case and fun to look into. It’s tempting almost enough to actually compare the bytecode (wish you had posted it so I could be lazy). Also, there’s a good chance the performance differs on how the code was compiled (ergo, using OpenJDK versus Sun/Oracle’s JDK). The bytecode compiler, if written so, could see your fixed concat operands and perhaps compile a more optimized code path than if using StringBuilder which could imply slower, more generic operations.

  2. Anonymous

    These two are very common class in java. from difference between StringBuffer and StringBuilder in javaStringBuffer is very good with mutable String but it has one disadvantage all its public methods are synchronized which makes it thread-safe but same time slow. In JDK 5 they provided similar class called StringBuilder in Java which is a copy of StringBuffer but without synchronization. Try to use StringBuilder whenever possible it performs better in most of cases than StringBuffer class.

Leave a comment