web-dev-qa-db-ja.com

Java:String concat vs StringBuilder-最適化されているので、どうすればよいですか?

この答え では、とにかくString連結がStringBuilder操作に最適化されていると(暗示している)ので、コードを書くときにソースにStringBuilderコードを書く理由はありますか?私の使用例はOPの質問とは異なることに注意してください。何千もの行を連結/追加しているからです。

自分自身を明確にするために、私はそれぞれの違いをよく知っていますが、実際にはStringBuilderコードを書く価値があるかどうかわかりません。読みにくいため、おそらくより遅いいとこであるStringクラスが自動的に変換されますとにかくコンパイルプロセス。

46
Soyuz

StringBuilder vs +は、実際に使用しているコンテキストに依存します。

通常、JDK 1.6以降を使用すると、コンパイラはStringBuilderを使用して文字列を自動的に結合します。

String one = "abc";
String two = "xyz";
String three = one + two;

これでコンパイルされますString three as:

String three = new StringBuilder().append(one).append(two).toString();

これは非常に役立ち、ランタイムを節約します。ただし、このプロセスは常に最適とは限りません。例:

String out = "";
for( int i = 0; i < 10000 ; i++ ) {
    out = out + i;
}
return out;

バイトコードにコンパイルし、生成されたバイトコードを逆コンパイルすると、次のようになります。

String out = "";
for( int i = 0; i < 10000; i++ ) {
    out = new StringBuilder().append(out).append(i).toString();
}
return out;

コンパイラーは内部ループを最適化しましたが、確かに可能な限り最適な最適化を行っていません。コードを改善するには、次を使用できます。

StringBuilder out = new StringBuilder();
for( int i = 0 ; i < 10000; i++ ) {
    out.append(i);
}
return out.toString();

これは、コンパイラが生成したコードよりも最適であるため、効率的なコードが必要な場合は、StringBuilder/StringBufferクラスを使用してコードを記述する必要があります。現在のコンパイラは、ループ内の文字列の連結を処理するのに優れていませんが、これは将来変更される可能性があります。

StringBuilderを手動で適用する必要がある場所を注意深く確認し、コードの可読性を低下させない場所で使用する必要があります。

注:JDK 1.6を使用してコードをコンパイルし、バイトコードを吐き出すjavapプログラムを使用してコードを逆コンパイルしました。解釈は非常に簡単で、コードを最適化しようとするときに参照するのに役立つ参照であることがよくあります。コンパイラは舞台裏でコードを変更するので、コンパイラが何をするのかを見るのは常に面白いです!

112
Tom Cammann

あなたの質問のキーフレーズは「おそらく遅い」です。これが実際にボトルネックであるかどうかを特定し、どちらが速いかを確認する必要があります。

このコードを書き込もうとしているが、まだ書いていない場合は、よりわかりやすいものを書き、必要であればそれがボトルネックかどうかを確認してください。

より高速であると思われるコードを使用することは理にかなっていますが、両方が同等に読み取り可能である場合、実際に時間をかけて、必要のないときにどちらが速いかを見つけるのは時間の無駄です。パフォーマンスが許容範囲を超えるまで、パフォーマンスを上回る可読性。

3
jmoreno

場合によって異なりますが、StringBuilderは少し高速であると考えられています。ループ内で連結を行う場合は、StringBuilderを使用することをお勧めします。

とにかく、コードのプロファイルとベンチマークを行うことをお勧めします(このような大規模な追加を行う場合)。

ただし、不変なStringではなく、StringBuilderのインスタンスは可変であり、スレッド間で共有されることはありません(実際に何をしているのかを本当に理解していない限り)。

2
bssstudio

私はあなたの質問を誤解したかもしれませんが、StringBuilderはStringsを追加するときの方が高速です。そのため、「数千行」を追加する場合は、StringBuilder(またはマルチスレッドアプリを実行している場合はStringBuffer)を使用する必要があります。

(コメントのより完全な回答)

0
cldjr