Visual C# .NET で文字列連結のパフォーマンスを上げる方法

この記事は、以前は次の ID で公開されていました: JP306822
Microsoft Visual JScript .NET については、次の資料を参照してください。306823
Microsoft Visual Basic .NET については、次の資料を参照してください。306821

この資料では、次の Microsoft .NET Framework クラス ライブラリの名前空間を参照しています。
  • System.Text

この資料の内容

概要
この資料では、従来の文字列連結方法よりも利点のある StringBuilder クラスの使用について、手順を追って説明します。.NET Framework では文字列は不変です (参照テキストは最初に割り当てられた後、読み取り専用になります)。これはパフォーマンス上多くの利点がありますが、C/C++ の文字列操作に慣れた開発者にとっては多少困難な部分があります。

.NET Framework の文字列の説明

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

しかし、.NET Framework には文字列連結を最適化する StringBuilder クラスが用意されています。StringBuilder には、C/C++ で文字配列を使用する場合と同様の利点があり、必要に応じて自動的にバッファ サイズを拡張し、長さを監視します。この資料のサンプル アプリケーションでは StringBuilder クラスの使用法を説明し、連結のパフォーマンスを比較します。

デモ アプリケーションのビルドと実行

  1. Visual Studio .NET を起動して、新しい Visual C# コンソール アプリケーションを作成します。
  2. 次のコードでは、30 文字を 5,000 回連結するのにかかる時間を、+= 文字列連結演算子を使用する場合と StringBuilder クラスを使用する場合それぞれについて計測します。次のコードを Main プロシージャに追加します。
    const int sLen=30, Loops=5000;DateTime sTime, eTime;int i;string sSource = new String('X', sLen);string sDest = "";// // Time string concatenation.// sTime = DateTime.Now;for(i=0;i<Loops;i++) sDest += sSource;eTime = DateTime.Now;Console.WriteLine("Concatenation took " + (eTime - sTime).TotalSeconds + " seconds.");// // Time StringBuilder.// sTime = DateTime.Now;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();eTime = DateTime.Now;Console.WriteLine("String Builder took " + (eTime - sTime).TotalSeconds + " seconds.");// // 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 6.208928 seconds.
    String Builder took 0 seconds.

    Press ENTER to finish...
  4. Enter キーを押してアプリケーションの実行を終了し、コンソール ウィンドウを閉じます。

トラブルシューティング

  • ASPX Web フォームのようにデータのストリーム処理をサポートする環境の場合、またはアプリケーションでデータをディスクに書き込む場合は、連結または StringBuilder のバッファ オーバーヘッドを回避することを検討し、Response.Write メソッド、または対象のストリームに適したメソッドを使って、ストリームにデータを直接書き込むようにします。
  • StringBuilder クラスを必要になるたびに再度割り当てず、定義済みの StringBuilder クラスを再利用するようにします。これによりヒープの増大を制限し、ガーベジ コレクションを減らします。いずれの場合も、StringBuilder クラスを使用することにより、+ 演算子を使用するよりもさらに効果的にヒープを使用できます。
関連情報
StringBuilder クラスには、この資料では説明されていない、インプレースで文字列を操作するメソッドが他にも多数あります。詳細については、オンライン ヘルプで "StringBuilder" を検索してください。

関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 306822 (最終更新日 2004-07-15) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
プロパティ

文書番号:306822 - 最終更新日: 09/22/2005 10:15:05 - リビジョン: 2.2

Microsoft Visual C# .NET 2002 Standard Edition

  • kbhowto kbhowtomaster kbperformance KB306822
フィードバック