19

重複の可能性:
String vs StringBuilder

VB.NET を手に入れるために使用した書籍の一部を再訪しました。これを頭に入れているかどうかはわかりません.StringBuilderがどのように/何であるかを理解してください。

使用上のガイドラインは何ですか?2 つの文字列または 50 の文字列を連結している場合、それを使用するのが最善ですか?

または、文字列の合計長が 128 文字を超える場合は?

それとも、文字列を一緒に追加するために使用するたびに、パフォーマンス上の利点が見られますか?

どの場合、StringBuilder インスタンスを使用して SQL ステートメントを作成する方がよいstring.format("Select * from x where y = {0}",1)でしょうか?

別の変数を宣言して名前空間を含めることは、小さな文字列の連結には有益ではないことにいつも気付きましたが、今はよくわかりません。

申し訳ありませんが、多くのドキュメントが何を使用するかを示していますが、何が最適かはわかりません。

4

6 に答える 6

40

このトピックに関する記事があります。要約すると(ページの下部からコピー):

  • 自明でないループで連結する場合は、必ず StringBuilder を使用してください。特に、(コンパイル時に) ループで何回反復するかわからない場合は特にそうです。たとえば、一度に 1 文字ずつファイルを読み取り、+= 演算子を使用して文字列を作成すると、パフォーマンスが自殺する可能性があります。
  • 1 つのステートメントで連結する必要があるすべてを (読みやすく) 指定できる場合は、必ず連結演算子を使用してください。(連結する配列がある場合は、明示的に String.Concat を呼び出すことを検討してください。区切り文字が必要な場合は String.Join を呼び出してください。)
  • リテラルを複数の連結ビットに分割することを恐れないでください。結果は同じになります。たとえば、長いリテラルを数行に分割することで読みやすくすることができますが、パフォーマンスに悪影響を与えることはありません。
  • 連結の次の繰り返しに供給する以外の目的で連結の中間結果が必要な場合、StringBuilder は役に立ちません。たとえば、名と姓からフルネームを作成し、最後に 3 番目の情報 (ニックネームなど) を追加する場合、StringBuilder を使用しない場合にのみメリットがあります。他の目的で (名 + 姓) 文字列が必要です (Person オブジェクトを作成する例で行っているように)。
  • いくつかの連結を行うだけで、それらを個別のステートメントで実行したい場合は、どちらの方法で行ってもかまいません。どちらの方法がより効率的かは、関連する文字列のサイズ、連結の数、およびそれらが連結される順序によって異なります。コードの一部がパフォーマンスのボトルネックであると本当に信じている場合は、両方の方法でプロファイリングまたはベンチマークを行ってください。
于 2009-02-09T21:16:38.617 に答える
14

これが私の経験則です:

StringBuilderコンパイル時に連結の正確な数が不明な場合に最適です。

于 2009-02-09T21:14:48.777 に答える
3

Coding Horrorには、この問題に関する良い記事The Sad Tragedy of Micro-Optimization Theater があります。

于 2009-02-09T21:19:24.150 に答える
0

個人的には、連結する文字列が 1 つまたは 2 つ以上ある場合は StringBuilder を使用します。実際にパフォーマンスが向上するかどうかはわかりませんが、複数の文字列を通常に連結すると、実行するたびに文字列の余分なコピーが作成されるのに対し、StringBuilder を使用すると 1 つ保持されることを常に読んで、言われてきました。最終ToString()メソッドを呼び出すまでコピーします。

于 2009-02-09T21:17:31.813 に答える
0

臨界数は 6 であることが実験的に判明しました。6 つ以上の連結が連続している場合は、StringBuilder を使用する必要があります。これをどこで見つけたか思い出せません。

ただし、これを 1 行に記述するだけの場合は、次のように注意してください。

"qwert" + "yuiop" + "asdf" + "gh" + "jkl;" + "zxcv" + "bnm" + ",."

それは1つの関数呼び出しに変換されます(VB.netでの書き方がわかりません)

String.Concat("qwert", "yuiop", "asdf", "gh", "jkl;", "zxcv", "bnm", ",.");

したがって、すべての連結を 1 行で行っている場合は、StringBuilder を気にする必要はありません。String.Concat はすべての連結を一度に効果的に行うためです。それらをループで実行しているか、連続して連結している場合のみです。

于 2009-02-09T21:18:44.663 に答える
0

私のルール - For または Foreach ループで文字列を追加するときは、StringBuilder を使用します。

于 2009-02-09T21:19:38.500 に答える