この例では、StringBuffer は実際には StringBuilder よりも高速ですが、反対の結果が予想されていました。
これは、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 ですが、少なくとも全体的な比率は予想されるものと一致しています。