这是否与JIT进行的优化有关?有人知道为什么StringBuffer会比StringBuilder更快,即使它的方法是同步的吗?
以下是代码和基准测试结果:
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));
}
}
基准测试结果:
Using + operator : 17199609ns
Using StringBuffer : 244054ns
Using StringBuilder : 4351242ns
Diff '+'/Buff = 70.47460398108615
Diff Buff/Builder = 0.056088353624091696
更新:
感谢大家。热身确实是问题所在。一旦添加了一些热身代码,基准测试结果变为:
Using + operator : 8782460ns
Using StringBuffer : 343375ns
Using StringBuilder : 211171ns
Diff '+'/Buff = 25.576876592646524
Diff Buff/Builder = 1.6260518726529685
YMMV(你的经验可能有所不同),但总体比例符合预期。
StringBuffer
更快。 - ppeterka