50

この回答では、文字列の連結がとにかくStringBuilder操作に最適化されていることを示しています(暗示しています)。したがって、コードを作成するときに、ソースにStringBuilderコードを作成する理由はありますか?数十万行を連結/追加しているため、私のユースケースはOPの質問とは異なることに注意してください。

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

4

4 に答える 4

118

StringBuildervsの使用は、+実際に使用しているコンテキストに依存すると思います。

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

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

これは次のようにコンパイルString threeされます:

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バイトコードを吐き出すプログラムを使用してコードを逆コンパイルしました。解釈はかなり簡単で、コードを最適化しようとするときに参照するのに役立つことがよくあります。コンパイラはバックグラウンドでコードを変更するので、コンパイラが何をするかを見るのは常に興味深いことです。

于 2013-02-18T00:37:13.560 に答える
3

あなたの質問のキーワードは「おそらく遅い」です。これが本当にボトルネックであるかどうかを識別してから、どちらが速いかを確認する必要があります。

このコードを作成しようとしているが、まだ作成していない場合は、わかりやすいものを作成し、必要に応じてボトルネックかどうかを確認してください。

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

于 2013-02-18T00:20:34.123 に答える
2

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

とにかく、私はあなたにあなたのコードをプロファイリングしてベンチマークすることをお勧めします(あなたがそのような大規模な追加をしているなら)。

ただし、注意してください。StringBuilderのインスタンスは可変であり、不変であるStringとは対照的に、スレッド間で共有されません(実際に何をしているのかを理解している場合を除きます)。

于 2013-02-18T00:09:38.373 に答える
0

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

(コメントでより徹底的な答え)

于 2013-02-18T00:07:34.257 に答える