So StringBuilder is supposed to be faster. But how much faster? Let’s see… java
I create a small program to stress test StringBuffer vs.StringBuilder. As a reference I also do straight Stringconcatenation. In a big loop I just add one character to aString/StringBuffer/StringBuilder. I also play with the initial memory allocation for the StringBuilder and StringBuffercases. Here is the code: app
This example allows me to play with the number of iterations, the initial buffer size (not for String concatenation) and which tests I run. Nothing smart, just commenting what I don’t want to run. oop
The numbers are not really important but the percentage difference is. ui
The first run with all three tests and the default capacity: this
Iterations: 100000
Capacity : 16
concatStrBuff -> length: 100000 time: 16
concatStrBuild -> length: 100000 time: 15
concatStrAdd -> length: 100000 time: 10437 spa
This makes it clear I should never use plain String concatenation in big loops. Of course if you just concatenate a few strings once in a while this doesn’t matter. The explanation is clear from the bytecode generated for the loop in the concatStrAdd() method (fragment): code
The compiler uses a StringBuilder to concatenate Strings but unfortunately it creates one instance of it at every iteration. Compare it with the code generated for the loop in the concatStrBuild()method (fragment): orm
Increasing the initial capacity for StringBuffer andStringBuilder doesn’t make much difference. Clearly with only 100,000 iterations the numbers for StringBuffer andStringBuilder are just noise. three
Iterations: 100000
Capacity : 100000
concatStrBuff -> length: 100000 time: 15
concatStrBuild -> length: 100000 time: 16
concatStrAdd -> length: 100000 time: 10594 ip
Let’s crank it up… but without the String concatenation test because it will never finish.
Iterations: 100000000
Capacity : 16
concatStrBuff -> length: 100000000 time: 15142
concatStrBuild -> length: 100000000 time: 10891
Now it is pretty clear StringBuilder is much faster because it avoids synchronization.
Iterations: 100000000
Capacity : 100000000
concatStrBuff -> length: 100000000 time: 14220
concatStrBuild -> length: 100000000 time: 10611
Allocating all the memory at once does make some difference but nothing really spectacular. But if we look at how the memory allocation peaks we get some more food for thought:
Bump 1: StringBuffer with buffer 100000000
Bump 2: StringBuffer with buffer 16
Bump 3: StringBuilder with buffer 100000000
Bump 4: StringBuilder with buffer 16
So StringBuilder is faster by a good percentage (34% on my machine in this case) but remember that it is not thread safe.