JavaでのStringBuilderとStringBuffer

1。概要

この短い記事では、JavaのStringBuilderStringBufferの類似点と相違点を見ていきます。

簡単に言えば、StringBuilderStringBufferの代わりとしてJava1.5で導入されました。

2.類似点

StringBuilderStringBufferはどちらも、可変の文字シーケンスを保持するオブジェクトを作成します。これがどのように機能し、不変のStringクラスとどのように比較されるかを見てみましょう。

String immutable = "abc"; immutable = immutable + "def";

「def」を追加して同じオブジェクトを変更しているように見えるかもしれませんが、Stringインスタンスは変更できないため、新しいオブジェクトを作成しています。

StringBufferまたはStringBuilderのいずれかを使用する場合、append()メソッドを使用できます。

StringBuffer sb = new StringBuffer("abc"); sb.append("def");

この場合、新しいオブジェクトは作成されませんでした。sbインスタンスでappend()メソッドを呼び出し、その内容を変更しました。StringBufferStringBuilderは可変オブジェクトです。

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; }

デフォルトのスループットモードを使用しました。つまり、単位時間あたりの操作(スコアが高いほど良い)です。

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のパフォーマンスの向上どこでも置き換えることを正当化するには小さすぎる可能性があります。ある実装を別の実装に置き換えるためのあらゆる種類の作業を行う前に、アプリケーションのプロファイルを作成し、その実行時のパフォーマンス特性を理解することをお勧めします。

最後に、いつものように、ディスカッション中に使用されたコードはGitHubにあります。