JavaでのStringBuilderとStringBuffer
1. 概要
この短い記事では、JavaのStringBuilderとStringBufferの類似点と相違点を見ていきます。
簡単に言うと、 StringBuilder は、StringBufferの代わりとしてJava1.5で導入されました。
2. 類似点
StringBuilderとStringBufferはどちらも、文字の可変シーケンスを保持するオブジェクトを作成します。これがどのように機能し、不変の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を使用できます。 ただし、 StringBufferに対するStringBuilderのパフォーマンスの向上は小さすぎて、どこでも置き換えることを正当化できない場合があります。 1つの実装を置き換えるためのあらゆる種類の作業を行う前に、アプリケーションのプロファイルを作成し、その実行時のパフォーマンス特性を理解することをお勧めします。他のと。
最後に、いつものように、ディスカッション中に使用されたコードは、GitHubのにあります。