Visual C# を使用して文字列連結のパフォーマンスを向上させる

この記事では、Visual C# で文字列連結のパフォーマンスを向上させる方法について説明します。

元の製品バージョン: Visual C#
元の KB 番号: 306822

概要

この記事では、従来の連結手法よりも クラスを使用する StringBuilder 利点について説明します。 Microsoft .NET Framework内の文字列は不変です (つまり、参照されるテキストは最初の割り当て後に読み取り専用です)。 これは多くのパフォーマンス上の利点を提供し、C/C++ 文字列操作手法に慣れている開発者にいくつかの課題をもたらします。

この記事では、.NET Framework クラス ライブラリ名前空間 を参照しますSystem.Text

.NET Framework内の文字列の説明

Visual C/C++ で文字列連結 strcat() を改善する手法の 1 つは、大きな文字配列をバッファーとして割り当て、文字列データをバッファーにコピーすることです。 .NET Frameworkでは、文字列は不変であり、インプレースで変更することはできません。 C# + 連結演算子は新しい文字列を作成し、大量のテキストを連結するとパフォーマンスが低下します。

ただし、.NET Frameworkには、StringBuilder文字列連結用に最適化されたクラスが含まれています。 これは、C/C++ で文字配列を使用するのと同じ利点を提供し、必要に応じてバッファー サイズを自動的に拡大し、長さを追跡します。 この記事のサンプル アプリケーションでは、 クラスの StringBuilder 使用方法を示し、パフォーマンスと連結を比較します。

デモ アプリケーションをビルドして実行する

  1. Visual Studio を起動し、新しい Visual C# コンソール アプリケーションを作成します。

  2. 次のコードでは、 += 連結演算子と クラスを StringBuilder 使用して、それぞれ 30 文字の連結を 5,000 回実行します。 このコードを メイン プロシージャに追加します。

    const int sLen = 30, Loops = 5000;
    int i;
    string sSource = new String('X', sLen);
    string sDest = "";
    
    // Time string concatenation.
    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
    for (i = 0; i < Loops; i++) sDest += sSource;
    stopwatch.Stop();
    Console.WriteLine($"Concatenation took {stopwatch.ElapsedMilliseconds} ms.");
    
    // Time StringBuilder.
    stopwatch.Restart();
    System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
    for (i = 0; i < Loops; i++) 
        sb.Append(sSource);
    sDest = sb.ToString();
    stopwatch.Stop();
    Console.WriteLine($"String Builder took {stopwatch.ElapsedMilliseconds} ms.");
    
    // Make the console window stay open
    // so that you can see the results when running from the IDE.
    Console.WriteLine();
    Console.Write("Press Enter to finish ... ");
    Console.Read();
    
  3. アプリケーションを保存します。 F5 キーを押してコンパイルし、アプリケーションを実行します。 コンソール ウィンドウには、次のような出力が表示されます。

    Concatenation took 348 ms.
    String Builder took 0 ms.
    Press ENTER to finish...
    
  4. Enter キーを押してアプリケーションの実行を停止し、コンソール ウィンドウを閉じます。

トラブルシューティング

  • ASPX Web フォームやアプリケーションなど、データのストリーミングをサポートする環境でデータをディスクに書き込む場合は、連結または StringBuilderのバッファー オーバーヘッドを回避することを検討し、該当するストリームのメソッドまたは適切なメソッドを使用して Response.Write ストリームに直接データを書き込みます。

  • 必要なたびに再割り当てするのではなく、既存 StringBuilder class のものを再利用してみてください。 ヒープの拡張を制限し、ガベージ コレクションを減らします。 どちらの場合も、 クラスを StringBuilder 使用すると、 演算子を使用するよりもヒープを効率的に + 使用できます。

関連情報

クラス StringBuilder には、この記事で説明されていないインプレース文字列操作用の他の多くのメソッドが含まれています。 詳細については、オンライン ヘルプで を StringBuilder 検索してください。