JavaのStringBuilderとStringBuffer
1. 概要
この短い記事では、JavaのStringBuilderとStringBufferの類似点と相違点を見ていきます。
簡単に言えば、StringBuilderはStringBufferの代わりとしてJava1.5で導入されました。
2. 類似点
StringBuilderとStringBufferの両方が、a mutable sequence of charactersを保持するオブジェクトを作成します。 これがどのように機能するか、そして不変のStringクラスとどのように比較されるかを見てみましょう。
String immutable = "abc";
immutable = immutable + "def";
“def”を追加して同じオブジェクトを変更しているように見えるかもしれませんが、Stringインスタンスは変更できないため、新しいオブジェクトを作成しています。
StringBufferまたはStringBuilder,のいずれかを使用する場合、append()メソッドを使用できます。
StringBuffer sb = new StringBuffer("abc");
sb.append("def");
この場合、新しいオブジェクトは作成されませんでした。 sbインスタンスでappend()メソッドを呼び出し、その内容を変更しました。 StringBufferとStringBuilderは可変オブジェクトです。
3. 違い
StringBufferは同期されているため、スレッドセーフです。 StringBuilderはStringBuffer APIと互換性がありますが、同期の保証はありません。
スレッドセーフな実装ではないため、より高速であり、スレッドセーフの必要がない場所で使用することをお勧めします。
3.1. パフォーマンス
小さな反復では、パフォーマンスの違いはわずかです。 JMHを使用して簡単なマイクロベンチマークを実行してみましょう。
@State(Scope.Benchmark)
public static class MyState {
int iterations = 1000;
String initial = "abc";
String suffix = "def";
}
@Benchmark
public StringBuffer benchmarkStringBuffer(MyState state) {
StringBuffer stringBuffer = new StringBuffer(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuffer.append(state.suffix);
}
return stringBuffer;
}
@Benchmark
public StringBuilder benchmarkStringBuilder(MyState state) {
StringBuilder stringBuilder = new StringBuilder(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuilder.append(state.suffix);
}
return stringBuilder;
}
デフォルトのThroughputモードを使用しました。 単位時間あたりの操作(スコアが高いほど良い):
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops/s
反復回数を1kから1mに増やすと、次のようになります。
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops/s
ただし、これはマイクロベンチマークであり、アプリケーションの実際の実際のパフォーマンスに実際の影響を与える場合と与えない場合があることに注意してください。
4. 結論
簡単に言えば、StringBufferはスレッドセーフな実装であるため、StringBuilderよりも低速です。
シングルスレッドプログラムでは、StringBuilderを使用できます。 ただし、the performance gain of StringBuilder over StringBuffer may be too small to justify replacing it everywhere.ある実装を別の実装に置き換えるためのあらゆる種類の作業を行う前に、アプリケーションのプロファイルを作成し、その実行時のパフォーマンス特性を理解することをお勧めします。
最後に、いつものように、議論中に使用されたコードはover on GitHubで見つけることができます。