String goes StringBuffer
Let me first tell you what is StringBuilder. StringBuilder is a class analogous to StringBuffer added in JDK 1.5. This class is designed to use in place where StringBuffer is used by single thread(like in most
of the cases). According to documentation, StringBuilder should work faster than StringBuffer. So ” thread unsafe, fast”.
I was reading one of the posts of orkut Java community asking “what is this capacity in StringBuffer and even we can add two strings from String class why to go for StringBuffer”. Valid question ! GC need to work little more in case of String, but thats fair.
No don’t use String class for concatenation operation, always use StringBuffer / StringBuilder and let me tell you why ?
This is a simple Java code for string addition in String and StringBuffer:
class StringTest {
public static void main(String[] args)
{
String s = “just a string”;
s = s + “add me too”;
System.out.println(s);
/*
StringBuffer s = new StringBuffer(”just a string”);
//StringBuilder s = new StringBuilder(”just a string”);
s = s.append(”add me too”);
System.out.println(s);
*/
}
}
Alright, now have a look on the bytecode of this program.
>> javac StringTest.java
>> javap -c StringTest
Compiled from “StringTest.java” class StringTest extends java.lang.Object{ StringTest(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object.“:()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2; //String just a string 2: astore_1 3: new #3; //class java/lang/StringBuilder 6: dup 7: invokespecial #4; //Method java/lang/StringBuilder.“:()V 10: aload_1 11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/ String;)Ljava/lang/StringBuilder; 14: ldc #6; //String add me too 16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;) Ljava/lang/StringBuilder; 19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_1 23: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream; 26: aload_1 27: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return }
Just see line no. 11. Interesting, the plus sign we used for addition is not as innocent as it looks. String itself use StringBuffer(StringBuilder) to add two strings and hence taking much more time than normal append operation done by StringBuffer. Let me give you more evidence, run verbose option and check the time
>> javac -verbose StringTest.java
and check the other one, that is, with StringBuffer one.
You can clearly figure out the time difference and make a try with StringBuilder, time should reduce furthermore.











Java,JavaScript,Threading,
Optimization and more with Vaibhav 



June 16th, 2008 at 5:24 am
nice read …
you said .. String itself use StringBuffer(StringBuilder) to add two strings … does it always use StringBuilder .. or depending upon SOME factors … when does it use StringBuffer and when does it use StringBuilder ??
http://lavnish.blogspot.com/2008/06/string-buffer-vs-stringbuilder-vs.html
June 16th, 2008 at 1:45 pm
That’s really old news, in 2008, isn’t it?
June 17th, 2008 at 6:03 am
Thanks Lavnish,
When you use thread operation it will use StringBuffer else it will use StringBuilder. As you know StringBuilder - thread unsafe, fast.
Thanks Dimitris: Ya its very old news. I am not blogging for new flashes news, just blog for conceptual things which we have to keep in mind :-). But you have a point, let me blog something fresh and new
June 17th, 2008 at 10:00 pm
[...] w3hJava What, Why, When and How of Java, JavaFX and related technologies ← String goes StringBuffer [...]
July 30th, 2008 at 4:15 pm
For a mundane reason I will not go into, we were trying to determine the fastest way to concatenate n number of strings together, with a defined delimeter. The team tried a bunch of different ways to do this (some just plain bad, for contrast you understand….) and we ran benchmarks on them. The long and the short of it for one million operations was:
Simple Concatenation: 1016 ms.
target = A + delim + B + delim + C + delim + D + delim + E;
New StringBuilder: 875 ms.
buff.append(A).append(delim).append(B).append(delim).append(C).append(delim)
.append(D).append(delim).append(E);
Reusing StringBuilder: 657 ms.
buff.append(A).append(delim).append(B).append(delim).append(C).append(delim)
.append(D).append(delim).append(E);
The trick with reusing the StringBuilder was a utility (FastConcat) that maintained a ThreadLocal. On the first call, a new StringBuilder was created an assigned to the ThreadLocal. When a thread requested a FastConcat, it took the thread’s exclusive StringBuilder and truncated it and then returned it. Downside was that you purge the contents every time you request the FastConcat, but we did not have any use cases for long living buffers anyway.
So the difference between example 2 and 3 was clearly in the overhead of object creation. More over, FastConcat has a nice pleasant appending interface:
String FastConcat.append(String…args)
There was actually one faster implementation (about 340 ms) where the developer ingeniously used a map to cache existing concatenated segments. The only downside was the memory overhead of the cache. However, if you know that you will be frequently concatenating the same small set of values over and over, and speed is paramount, it’s not a bad way to go.
I think I will apply for that job… the one with the title of “Senior String Concatenation Engineer”…..