この記事では、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
クラスの使用方法を示し、パフォーマンスと連結を比較します。
デモ アプリケーションをビルドして実行する
Visual Studio を起動し、新しい Visual C# コンソール アプリケーションを作成します。
次のコードでは、
+=
連結演算子と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();
アプリケーションを保存します。 F5 キーを押してコンパイルし、アプリケーションを実行します。 コンソール ウィンドウには、次の例のような出力が表示されます。
Concatenation took 348 ms. String Builder took 0 ms. Press ENTER to finish...
Enter キーを押してアプリケーションの実行を停止し、コンソール ウィンドウを閉じます。
トラブルシューティング
ASPX Web フォームやアプリケーションなど、データのストリーミングをサポートする環境でデータをディスクに書き込む場合は、連結または
StringBuilder
のバッファー オーバーヘッドを回避し、Response.Write
メソッドまたは該当するストリームの適切なメソッドを使用してストリームに直接データを書き込むことを検討してください。必要なたびに再割り当てするのではなく、既存の
StringBuilder class
を再利用してみてください。 ヒープの増加を制限し、ガベージ コレクションを減らします。 どちらの場合も、StringBuilder
クラスを使用すると、+
演算子を使用するよりもヒープを効率的に使用できます。
関連情報
StringBuilder
クラスには、この記事では説明されていないインプレース文字列操作のための他の多くのメソッドが含まれています。 詳細については、オンライン ヘルプで StringBuilder
を検索してください。