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つのオブジェクトが作成されます。

  1. String位置0でのオブジェクト
  2. StringBuffer位置10でのオブジェクト
  3. 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

Reggie Hutchersonは、Sunのテクノロジーエバンジェリストです。彼は、J2SEとHotSpotパフォーマンスエンジンに集中して、世界中のSunのJava 2Platformテクノロジーを広めています。

このトピックの詳細

  • 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によって公開されました。