web-dev-qa-db-ja.com

StringBuilderを使用する場合

StringBuilderの利点を理解しています。

ただし、2つの文字列を連結する場合は、StringBuilderを使用せずに行う方が良い(高速である)と想定します。これは正しいです?

StringBuilderを使用すると、どの時点(文字列の数)で改善されますか?

64
Shiraz Bhaiji

ジェフ・アトウッドによる 「マイクロ最適化劇場の悲劇」 を読むことをお勧めします。

単純連結とStringBuilderと他のメソッドを扱います。

さて、あなたがいくつかの数字とグラフを見たいなら、リンクをたどってください;)

69
Alex Bagnolini

しかし、2つの文字列を連結したい場合は、StringBuilderを使用せずに行う方が良い(速い)と思います。これは正しいです?

それは確かに正しいです、あなたは正確に非常によく説明された理由を見つけることができます:

http://www.yoda.arachsys.com/csharp/stringbuilder.html

まとめ:文字列を一度に連結できる場合

var result = a + " " + b  + " " + c + ..

stringBuilderを使用せずにコピーを作成することをお勧めします(結果の文字列の長さは事前に計算されます)。

のような構造用

var result = a;
result  += " ";
result  += b;
result  += " ";
result  += c;
..

新しいオブジェクトは毎回作成されるため、StringBuilderを検討する必要があります。

最後に、この記事ではこれらの経験則を要約します。

経験則

では、StringBuilderをいつ使用し、文字列連結演算子をいつ使用する必要がありますか?

  • 自明ではないループで連結している場合は、特にStringBuilderを使用してください。特に、ループで実行する反復回数が(コンパイル時に)わからない場合は特に注意してください。たとえば、ファイルを一度に1文字ずつ読み取り、+ =演算子を使用して文字列を作成すると、パフォーマンスが自殺する可能性があります。

  • 1つのステートメントで連結する必要のあるすべてを(読みやすいように)指定できる場合は、連結演算子を明確に使用してください。 (連結するものの配列がある場合は、String.Concatを明示的に呼び出すことを検討してください。区切り文字が必要な場合は、String.Joinを呼び出すことを検討してください。)

  • リテラルをいくつかの連結ビットに分割することを恐れないでください-結果は同じになります。たとえば、パフォーマンスを損なうことなく、長いリテラルを複数の行に分割することで、読みやすくすることができます。

  • 連結の次の反復を供給する以外の何かのために連結の中間結果が必要な場合、StringBuilderは役に立ちません。たとえば、姓と名からフルネームを作成し、最後に3番目の情報(ニックネームなど)を追加する場合、StringBuilderを使用するメリットはありません。他の目的のために(名+姓)文字列が必要です(Personオブジェクトを作成する例で行うように)。

  • 実行する連結がいくつかあり、それらを別々のステートメントで実行したい場合は、どの方法を使用してもかまいません。どちらの方法がより効率的かは、文字列のサイズの連結の数、およびそれらが連結される順序に依存します。コードの一部がパフォーマンスのボトルネックになると本当に信じる場合は、両方の方法でプロファイルまたはベンチマークします。

39
Peter

System.Stringは不変オブジェクトです。つまり、コンテンツを変更するたびに新しい文字列が割り当てられるため、時間がかかります(そしてメモリが必要ですか?)。 StringBuilderを使用すると、新しいコンテンツを割り当てることなく、オブジェクトの実際のコンテンツを変更できます。

したがって、文字列に多くの変更を加える必要がある場合は、StringBuilderを使用します。

11

そうではありません... large文字列を連結する場合、またはループのように多くの連結がある場合は、StringBuilderを使用する必要があります。

8
Bobby

ただし、2つの文字列を連結する場合は、StringBuilderを使用せずに連結する方が適切で高速であると想定します。これは正しいです?

はい。しかし、もっと重要なことは、そのような状況でバニラStringを使用することは、はるかに多くの読み込み可能です。一方、ループで使用することは理にかなっており、連結と同じくらい読みやすくすることもできます。

特定の連結数をしきい値として引用する経験則に注意してください。ループ(およびループのみ)で使用することは、おそらく同じように便利で、覚えやすく、より意味があります。

4
Konrad Rudolph

決定的な答えはなく、経験則のみです。私の個人的なルールは次のようになります。

  • ループで連結する場合は、常にStringBuilderを使用します。
  • 文字列が大きい場合は、常にStringBuilderを使用します。
  • 連結コードが整頓されていて画面上で読みやすい場合は、おそらく大丈夫です。
    そうでない場合は、StringBuilderを使用します。
4
LukeH

言い換えると

それからあなたは3つまで、それ以上でもそれ以下でも数えません。 3はあなたが数える数であり、数える数は3でなければならない。 4つは数えず、2つも数えません。ただし、3つに進む場合を除きます。 3番目の数字である3番目に到達したら、アンティオキアの聖なる手G弾をロブベスト

通常、3つ以上の文字列が連結されるコードブロックには文字列ビルダーを使用します。

4
Russell Steen
  • ループ内で文字列を連結する場合、通常のStringの代わりにStringBuilderの使用を検討する必要があります
  • 単一の連結の場合、実行時間の違いがまったく表示されない場合があります

これがポイントを証明する簡単なテストアプリです:

class Program
{
    static void Main(string[] args)
    {
        const int testLength = 30000;
        var StartTime = DateTime.Now;

        //TEST 1 - String
        StartTime = DateTime.Now;
        String tString = "test string";
        for (int i = 0; i < testLength; i++)
        {
            tString += i.ToString();
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 2000 ms

        //TEST 2 - StringBuilder
        StartTime = DateTime.Now;
        StringBuilder tSB = new StringBuilder("test string");
        for (int i = 0; i < testLength; i++)
        {
            tSB.Append(i.ToString());
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 4 ms

        Console.ReadLine();
    }
}

結果:

  • 30'000反復

    • ストリング-2000ミリ秒
    • StringBuilder-4ミリ秒
  • 1000回の繰り返し

    • ストリング-2ミリ秒
    • StringBuilder-1ミリ秒
  • 500回の繰り返し

    • ストリング-0ミリ秒
    • StringBuilder-0ミリ秒
4

連結数(a + b + c ...)を物理的に入力できる限り、大きな違いはありません。 Nの2乗(N = 10で)は100倍の減速であり、それほど悪くないはずです。

大きな問題は、何百もの文字列を連結する場合です。 N = 100では、10000X倍の速度低下が発生します。それはかなり悪いです。

3
wisty

使用するタイミングと使用しないタイミングの間に細かい境界線があるとは思わない。もちろん、誰かが黄金の条件を明らかにするためにいくつかの広範なテストを行わない限り。

私にとっては、2つの巨大な文字列を連結するだけならStringBuilderは使用しません。不確定なカウントのループがある場合は、ループが小さなカウントである場合でもそうです。

2
o.k.w

単一の連結は、StringBuilderを使用する価値はありません。私は通常、経験則として5つの連結を使用しました。

1
Matt Wrock

StringBuilderクラスは、変更可能な文字列の操作を可能にする一連のメソッドを開発者に提供します。新しいオブジェクトを作成せずに文字列を変更する場合に使用できます。通常の文字列連結のボトルネックの問題。

StringBuilderクラスを使用すると、ループで多くの文字列を連結する際のパフォーマンスが向上します。

以下は、.NETのStringBuilderクラスを使用して文字列を操作するために実行できるいくつかの操作のリストです。

追加:現在のStringBuilderの最後に情報を追加します。

AppendFormat:文字列で渡された書式指定子を書式付きテキストに置き換えます。

Insert:現在のStringBuilderの指定されたインデックスに文字列またはオブジェクトを挿入します。

Remove:現在のStringBuilderから指定した数の文字を削除します。

Replace:指定したインデックスの指定した文字を置き換えます。

0