Why is StringBuilder slower than StringBuffer?
java, stringbuffer, stringbuilder
Solution
I had a look at your code, and the most likely reason that `StringBuilder` it appears to be slower is that your benchmark is not properly taking account of the effects of JVM warmup. In this case:
- the JVM startup will generate an appreciable amount of garbage which needs to be dealt with, and
- JIT compilation may kick in partway though the run.
Either or both of these could add to the time measured for the `StringBuilder` part of your test.
Please read the answers to this Question for more details: How do I write a correct micro-benchmark in Java?
Problem
In this example, StringBuffer is actually faster than StringBuilder, whereas I would have expected opposite results. Is this something to do with optimizations being made by the JIT ? Does anyone know why StringBuffer would be faster than StringBuilder, even though it's methods are synchronized ? Here's the code and the benchmark results: ``` public class StringOps { public static void main(String args[]) { long sConcatStart = System.nanoTime(); String s = ""; for(int i=0; i<1000; i++) { s += String.valueOf(i); } long sConcatEnd = System.nanoTime(); long sBuffStart = System.nanoTime(); StringBuffer buff = new StringBuffer(); for(int i=0; i<1000; i++) { buff.append(i); } long sBuffEnd = System.nanoTime(); long sBuilderStart = System.nanoTime(); StringBuilder builder = new StringBuilder(); for(int i=0; i<1000; i++) { builder.append(i); } long sBuilderEnd = System.nanoTime(); System.out.println("Using + operator : " + (sConcatEnd-sConcatStart) + "ns"); System.out.println("Using StringBuffer : " + (sBuffEnd-sBuffStart) + "ns"); System.out.println("Using StringBuilder : " + (sBuilderEnd-sBuilderStart) + "ns"); System.out.println("Diff '+'/Buff = " + (double)(sConcatEnd-sConcatStart)/(sBuffEnd-sBuffStart)); System.out.println("Diff Buff/Builder = " + (double)(sBuffEnd-sBuffStart)/(sBuilderEnd-sBuilderStart)); } } ``` Benchmark results: ``` Using + operator : 17199609ns Using StringBuffer : 244054ns Using StringBuilder : 4351242ns Diff '+'/Buff = 70.47460398108615 Diff Buff/Builder = 0.056088353624091696 ``` UPDATE: Thanks to everyone. Warmup was indeed the problem. Once some warmup code was added, the benchmarks changed to: ``` Using + operator : 8782460ns Using StringBuffer : 343375ns Using StringBuilder : 211171ns Diff '+'/Buff = 25.576876592646524 Diff Buff/Builder = 1.6260518726529685 ``` YMMV, but at least the overall ratios agree with what would be expected.