StringBufferとString
Javaが提供StringBuffer
してString
授業をし、String
クラスを変更することはできません文字列を操作するために使用されます。簡単に言うと、型のオブジェクトString
は読み取り専用で不変です。このStringBuffer
クラスは、変更可能な文字を表すために使用されます。
これら2つのクラスのパフォーマンスの大きな違いは、単純な連結を実行する場合StringBuffer
よりも高速であるということですString
。でString
操作コード、文字列が日常連結されています。String
クラスを使用すると、連結は通常、次のように実行されます。
String str = new String( "Stanford"); str + = "Lost !!";
StringBuffer
同じ連結を実行するために使用する場合は、次のようなコードが必要になります。
StringBuffer str = new StringBuffer( "Stanford"); str.append( "Lost !!");
開発者は通常、上記の最初の例の方が効率的であると考えています。これは、append
連結の方法を使用する2番目の例は、+
演算子を使用して2つのString
オブジェクトを連結する最初の例よりもコストがかかると考えているためです。
+
オペレータは無実表示されますが、生成されたコードは、いくつかの驚きを生成します。StringBuffer
連結にforを使用すると、実際には、を使用するよりも大幅に高速なコードを生成できString
ます。これが当てはまる理由を見つけるには、2つの例から生成されたバイトコードを調べる必要があります。を使用した例のバイトコードはString
次のようになります。
0 new#7 3 dup 4 ldc#2 6 invokespecial#12 9 astore_1 10 new#8 13 dup 14 aload_1 15 invokestatic#23 18 invokespecial#13 21 ldc#1 23 invokevirtual#15 26 invokevirtual#22 29 astore_1
位置0から9のバイトコードは、コードの最初の行に対して実行されます。
String str = new String( "Stanford");
次に、位置10から29のバイトコードが連結のために実行されます。
str + = "Lost !!";
ここで物事は面白くなります。連結用に生成されたバイトコードはStringBuffer
オブジェクトを作成し、そのappend
メソッドを呼び出します。一時StringBuffer
オブジェクトはロケーション10で作成され、そのappend
メソッドはロケーション23で呼び出されます。String
クラスは不変であるStringBuffer
ため、連結にはを使用する必要があります。
StringBuffer
オブジェクトに対して連結が実行された後、オブジェクトをに変換し直す必要がありますString
。これはtoString
、ロケーション26のメソッドの呼び出しで実行されます。このメソッドはString
、一時StringBuffer
オブジェクトから新しいオブジェクトを作成します。この一時StringBuffer
オブジェクトの作成とその後のオブジェクトへの変換にString
は、非常にコストがかかります。
要約すると、上記の2行のコードにより、次の3つのオブジェクトが作成されます。
String
位置0でのオブジェクトStringBuffer
位置10でのオブジェクトString
位置26でのオブジェクト
それでは、以下を使用して例用に生成されたバイトコードを見てみましょうStringBuffer
。
0 new#8 3 dup 4 ldc#2 6 invokespecial#13 9 astore_1 10 aload_1 11 ldc#1 13 invokevirtual#15 16 pop
0から9の位置のバイトコードは、コードの最初の行に対して実行されます。
StringBuffer str = new StringBuffer( "Stanford");
次に、位置10〜16のバイトコードが連結のために実行されます。
str.append( "Lost !!");
最初の例の場合と同様に、このコードはオブジェクトのappend
メソッドを呼び出すことに注意してくださいStringBuffer
。ただし、最初の例とは異なり、一時を作成StringBuffer
してからString
オブジェクトに変換する必要はありません。このコードはStringBuffer
、位置0に1つのオブジェクト、、のみを作成します。
結論として、StringBuffer
連結はString
連結よりも大幅に高速です。明らかに、StringBuffer
可能な場合は、このタイプの操作でsを使用する必要があります。String
クラスの機能が必要な場合は、StringBuffer
連結にforを使用してから、への変換を1回実行することを検討してくださいString
。
このトピックの詳細
- 「JavaWorldは新しい毎週のJavaパフォーマンスコラムをデビューさせます」、Reggie Hutcherson(JavaWorld、 2000年3月)
//www.javaworld.com/jw-03-2000/jw-03-javaperf.html
- 「Javaパフォーマンスの基本」、Reggie Hutcherson(JavaWorld、 2000年3月)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_2.html
- 「パフォーマンスの問題ですか、それとも設計の問題ですか?」Reggie Hutcherson(JavaWorld、 2000年3月)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_3.html
- 「コンパイラの最適化」、Reggie Hutcherson(JavaWorld、 2000年3月)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html
このストーリー「StringBuffervsString」は、もともとJavaWorldによって公開されました。