Twitter

Tuesday, December 8, 2009

Java String concatenation Vs StringBuilder (using Dtrace object allocation probe)

"Item 51: Beware the performance of string concatenation" - Effective Java by Joshua Bloch.

Would you like to see how evil String concatenation in java is? continue reading...

Just to avoid these overheads later versions of java introduced StringBuffer(synchronized) and then StringBuilder(unsynchronized) classes.

Never ever use plain string concatenation in any production code. To know why run the following code on your machine...

public class StringSpeed {

public static void main(String[] args) {

try {
Thread.sleep(10000);
}
catch ( InterruptedException e ) {
e.printStackTrace();
}

int N = 100000;

String temp = "";
long start = System.currentTimeMillis();

for ( int i = 0; i < N; i++ ) {
temp = temp + "*";
}

long stop = System.currentTimeMillis();
System.out.println(stop - start);

StringBuilder tempBuilder = new StringBuilder();
start = System.currentTimeMillis();

for ( int i = 0; i < N; i++ ) {
tempBuilder.append("*");
}

stop = System.currentTimeMillis();
System.out.println(stop - start);
}
}
Since the first loop used plain string concatenation it took quite long... whereas the second loop crossed the finish line much quicker. output(on my machine): ======================
13328
8
Isn't the difference worth enough ;) ? The reason for the difference is that the concatenation using "+" has to create so many temp String/StringBuffer objects. To look how many we can use the following dtrace script.
:::object-alloc {
self->str_ptr = (char*) copyin(arg1, arg2+1);
self->str_ptr[arg2] = '\0';
self->classname = (string) self->str_ptr;
@allocs_count[self->classname] = count();
}
Output for first loop (yes!!! 90000+ Strings and 84000+ StringBuilders)
[Ljava/lang/Runnable; 1
java/lang/Shutdown$Lock 1
java/lang/Thread 1
java/security/AccessControlContext 1
[B 3
[[I 3
[S 6
[I 8
java/lang/StringBuilder 84414
java/lang/String 90416
[C 400008
For the second loop it is just...
[Ljava/lang/Runnable; 1
java/lang/Shutdown$Lock 1
java/lang/StringBuilder 1
java/lang/Thread 1
java/security/AccessControlContext 1
[B 2
[[I 2
[S 4
[I 7
java/lang/String 14
[C 62