10

毎秒約 5 件のメッセージを受信します。それぞれに文字列があり、受信したすべてのメッセージを含むマスター文字列に連結します

    string _masterText = "";
    public void AddNewMessage(string text)  // this is going to be call at least 5 times/second
    {
        _masterText += text;    
    }

これは適切な方法ですか?または、代わりに StringBuilder を使用する必要があります。

    StringBuilder _masterText = new StringBuilder();
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second
    {
         _masterText.Append(text);  
    }

ありがとう

4

6 に答える 6

14

通常は StringBuilder の方が適していると考えられていますが、この場合はどちらも使用しません。

StringBuilder を使用しても、その速度では、基になる文字バッファー自体がすぐに大きくなり、Large Object Heap でスタックしてしまいます。これにより、しばらく実行し続ける必要があるアプリケーションの状態に問題が発生します。

代わりに、a を使用して、新しいメッセージごとにそのメソッドをSystem.Collections.Generic.List<string>呼び出すだけです。.Add()これらのメッセージをどう処理するかによっては、別のコレクション タイプ (おそらく a Queue<string>) の方が適している場合もありますが、これが進むべき方向です。コレクションを使用すると、個々の文字列で使用されるメモリは、コレクション オブジェクトのサイズにカウントされません。代わりに、各文字列は参照用に数バイトしか追加しません。これにより、ラージ オブジェクト ヒープの圧縮に関する問題が発生するまでに、さらに長い時間がかかります。

コレクションに切り替えても問題が解決しない場合は、streamを使用して、文字列をディスクに書き込むことができます。このようにして、一度に RAM に複数の文字列が存在することはありません。現在、問題が発生する唯一の方法は、個々の文字列が 85000 バイト以上の場合です。

于 2010-07-29T02:44:14.160 に答える
8

Stringクラスは不変であることを忘れないでください。文字列を変更することはできません。文字列を「連結」しているときは、実際には新しい文字列を作成し、元の文字列の内容をそれにコピーしてから、新しい文字列の内容を追加しています。

大きな文字列を追加している場合、これは非常に急速にメモリを使用し始めます。

于 2010-07-29T02:45:30.743 に答える
3

stringbuilder が常に優れているにもかかわらず、200 ミリ秒ごとに非常に負担のかかるポーリングではありません。

于 2010-07-29T02:41:09.013 に答える
1

読むつもりなら、http://dotnetperls.com/stringbuilder-1での議論は非常に役立つと思います。速度とメモリ使用量に関する実際のメトリックへのリンクを確認してください。

また、Joel Spolsky の " Shlemeil the Painter's Algorithm "に関する議論もチェックしてください。彼は C のstrcat関数について話していますが、原則は C# の文字列に対するプラス演算子にも当てはまります。その上、それは笑いのために良いです。

一般に、追加操作を迅速に行う場合、または多くの大きな文字列を使用する場合は、StringBuilder をお勧めします。

于 2010-07-29T03:03:25.390 に答える
0

シナリオにもよります。stringbuilderオブジェクトと比較して、汎用リストを追加する方が速いことは間違いありません。ただし、汎用リストからのデータ取得時には、stringbuilderオブジェクトと比較してはるかに遅くなります。

stringbuilderは_masterText.ToString()を使用してすばやく戻りますが、汎用リストでは、反復を使用して値をプルする必要がある場合があります。そして、それは次のような高価なプロセスになります:-

  for (int x = 0; x < 100; x++)
    {
      Label3.Text += gen_list[x];
    }

またはあなたはで試すことができます

Label3.Text = string.Join( ""、gen_list.ToArray());

そうすると、取得操作が遅くなり、コストがかかり、CPUのスパイクに簡単に気付くことができます。

于 2010-07-29T09:44:42.920 に答える
0

StringBuilder はあなたの相棒です!

于 2010-07-29T02:41:53.717 に答える