:(一般的におよび.NET)C#で 文字列contatenationをは「安全」ですが、あなたが説明するようにタイトなループでそれを行うと、深刻なメモリ不足が発生し、負担をかける可能性がありますガベージコレクタで
あなたが話すエラーは何らかのリソースの消耗に関連していると推測されますが、例外を受け取ったかどうかなど詳細を提供できると便利です。アプリケーションが異常終了しましたか?
背景: .NET文字列は不変ですので、あなたはこのような連結行うとき:
string result = "";
result = "aaa"
string temp1 = result + "bbb";
result = temp1;
string temp2 = temp1 + "ccc";
result = temp2;
string temp3 = temp2 + "ddd";
result = temp3;
// ...
result = tempN + x;
この目的を:
var stringList = new List<string> {"aaa", "bbb", "ccc", "ddd", //... };
string result = String.Empty;
foreach (var s in stringList)
{
result = result + s;
}
を。これは、次のとほぼ同じです例えば、ループの周りに新しい一時的な文字列が割り当てられることを強調することです。
文字列が不変なので、ランタイムには代替オプションはありませんが、結果の最後に別の文字列を追加するたびに新しい文字列を割り当てることができます。
文字列は常に最新かつ最高の中間結果を指すように更新されますが、すぐにガベージコレクションの対象となるこれらの名前のない一時的な文字列が多数生成されています。
この連結の最後に、メモリに以下の文字列が格納されます(簡単にするため、ガベージコレクタはまだ実行されていないものとします)。
string a = "aaa";
string b = "bbb";
string c = "ccc";
// ...
string temp1 = "aaabbb";
string temp2 = "aaabbbccc";
string temp3 = "aaabbbcccddd";
string temp4 = "aaabbbcccdddeee";
string temp5 = "aaabbbcccdddeeefff";
string temp6 = "aaabbbcccdddeeefffggg";
// ...
これらの暗黙的な一時変数はすべて、すぐにガベージコレクションの対象となりますが、まだ割り当てられている必要があります。タイトなループで連結を実行する場合、これはガベージコレクタに多くの負担をかけることになります。それ以外の場合は、コードの実行が非常に遅くなります。私はこの最初の手のパフォーマンスの影響を見てきました。そして、連結された文字列が大きくなるにつれて、それは本当に劇的になります。
複数の文字列連結を行う場合は、常にStringBuilder
を使用することをお勧めします。StringBuilder
は可変バッファを使用して、文字列を構築するのに必要な割り当ての数を減らします。
StringBuilderバージョンに対して、文字列連結コードを貼り付けることはできますか?文字列連結とStringBuilderとの違いを得ることができると思う唯一の理由は、いくつかのもののオーバーロードが呼び出されますが、それは記述しているような効果はありません。 –
オリジナルコード: string filepath = path + fileroot + ".xml"; 更新されたコード: string filepath = new StringBuilder(パス) .Append(fileroot) .Append( "。xml")。ToString(); 私はいくつかの場所でそれを変更しました。これらはすべてメインループの前です。メインループの中で、私は常にStringBuilderを使用してXMLファイルの内容を構築してきました。 (私はXML APIを使用していません。なぜなら、XML APIの方が早かったからです。これは、すばやく汚れたプログラムになるはずです。) –