何がStringBuilderのRAM消費す。
-
02-07-2019 - |
質問
して業務をこなしているということは多数の大文字列concatenationsが、最近、うちのメモリの例外です。残念ながらアプリケーションのデバッグ、コードの選択肢はないことが起こっているので、お客様のサイトです。
では、日本へのオーバーホールのコードはどのように:のRAM消費特性のStringBuilder大文字列?
として特に彼らは比較的標準の文字列タイプです。サイズの文字列は10MBたものに関する問題は20応募を推奨いたします。
注意:ではないの速度が違います。
解決
連結を回避できる場合は、実行してください!
もしあなたがしなければ 連結する必要がありますが 見栄えのするソースコードは、 最初の方法。最適化されます 単一の文字列の場合。
+ =連結を使用しないでください。変更が多すぎます 背後では、明らかではありません そもそも私のコードから。私 むしろString.Concat()を使用することをお勧めします オーバーロード(2 文字列、3文字列、文字列配列)。 これにより、コードが明確に表示されます 驚くことなく、 自分でチェックを続けられるようにする 効率。
StringBuilderのターゲットサイズを推定してみてください。
より正確に推定できる 必要なサイズ、一時的ではない StringBuilderが必要とする文字列 内部を増やすために作成する バッファ。
パフォーマンスが問題になる場合は、Format()メソッドを使用しないでください。
に含まれるオーバーヘッドが多すぎる 可能であれば、形式の解析 次の場合、断片から配列を構築します 使用しているのは{x}の置換のみです。 Format()は読みやすいですが、 あなたがいるときに行くことの一つ 可能なすべてのパフォーマンスを絞り出す アプリケーションの
他のヒント
各時間StringBuilderのスペースでreallocates新しいバッファのサイズのバッファにコピーは古いキャラクターのバッファの取得GCい.できるだけ利用で十分(ここではx)のように2倍以上のメモリで販売するチャコットが勝どきに複割り当ていている最長の文字列やパスのコンストラクタのStringBuilderいpreallocateんなの慈しみは倍増再配分
ropesデータ構造に興味があるかもしれません。この記事:ロープ:理論と実践はそれらの利点を説明しています。 .NETの実装があるかもしれません。
[更新、コメントに回答する]
より少ないメモリを使用しますか?記事で memory を検索すると、ヒントが見つかります。
基本的に、はい、構造のオーバーヘッドにもかかわらず、必要なときにメモリを追加するだけです。 StringBuilderは、古いバッファを使い果たすと、はるかに大きなバッファ(すでに空のメモリを浪費している可能性がある)を割り当て、古いバッファを削除する必要があります(ガベージコレクションされますが、その間も多くのメモリを使用できます)。
.NETの実装は見つかりませんでしたが、少なくともC ++実装があります(SGIのSTL: http://www.sgi.com/tech/stl/Rope.html )。この実装を活用できるかもしれません。私が参照するページには、メモリのパフォーマンスに関する作業があります。
ロープはすべての問題の解決策ではないことに注意してください。ロープの有用性は、大きな文字列をどのように構築し、どのように使用するかに大きく依存します。記事は長所と短所を指摘しています。
Strigbuilderは、文字列の連結によって引き起こされるメモリの問題に対する完璧な解決策です。
特定の質問に答えるために、Stringbuilderには、文字列の長さが現在割り当てられているStringbuilderバッファの長さと等しい通常の文字列と比較して、一定サイズのオーバーヘッドがあります。バッファは結果として生じる文字列のサイズの2倍になる可能性がありますが、Stringbuilderに連結するとき、バッファがいっぱいになるまでメモリの割り当ては行われないため、本当に優れたソリューションです。
文字列と比較して、これは際立っています。
string output = "Test";
output += ", printed on " + datePrinted.ToString();
output += ", verified by " + verificationName;
output += ", number lines: " + numberLines.ToString();
このコードには、コード内にリテラルとして保存される4つの文字列があります。2つはメソッドで作成され、もう1つは変数から作成されます。このパターンを継続すると、GCが起動してクリーンアップするまで、指数関数的にメモリ使用量が増加します。
文字列ビルダーの正確なメモリパターンについては知りませんが、一般的な文字列はオプションではありません。
共通の文字列を使用すると、すべての連結によって別の文字列オブジェクトが2つ作成され、メモリ消費が急増するため、ガベージコレクターが頻繁に呼び出されます。
string a = "a";
//creates object with a
a += "b"
/creates object with b, creates object with ab, assings object with ab to "a" pointer