2009-05-26 10 views
1

私のアプリケーションでは、多くのDeflate圧縮ブロック(および他のタイプの圧縮と暗号化を含む)を含むファイルの圧縮を解除する必要があります。メモリプロファイリングは、デフレートストリームコンストラクタがアプリケーションのメモリの大半をその存続期間(54.19%、DeflateStream.readが12.96%、それ以外は2%未満)で割り当てることを示します。DeflateStreamを使用しているときにメモリを少なくすることはできますか?

各ファイルブロックは通常4KiB(圧縮解除)で、DeflateStreamのコンストラクタは32KiBよりもわずかに多く(おそらくスライディングウィンドウ用に)割り当てます。ガベージコレクターは、これらのすべての水溜まりの流れがほとんど時間のない状態で続く(1つは次のものが入る前に消え去る)ので、フィールドデーを持っています!さようならキャッシュ効率。

私はDeflateStreamを使い続けることができますが、もっと良い選択肢があるのでしょうか?ストリームをリセットしてもう一度使用する方法がありますか?

答えて

3

二つのコメント:

  • 私はあなたがこれらの一時バッファの割り当て(およびゼロ)にかかる時間の量は次のごくわずかであることを見つけると思います実際の圧縮解除に費やされた時間まで。
  • これらのバッファが非常に過渡的であるという事実は、アプリケーションの存続期間にわたってメモリの50%である可能性がありますが、同時に存在しないことを意味します。キャッシュの効率をあまり損なうものではないことに注意してください...私は、これらのバッファの大部分がキャッシュメモリに多くのデータを保存することはないと考えています。

要するに、デフレートストリーム(スピードまたは絶対メモリ使用のいずれか)で測定可能な問題がない限り、私はそのまま使用しています...あなたが知っているソリューションを使用する方が、それは対処するのが難しい全く異なる問題を持つかもしれません。

+0

私は時間プロファイリングをよく見て、あなたが正しいことを発見しました。時間の大部分は、出力を操作する関数に費やされているようです。 –

2

実際のパフォーマンス上の問題がありますか、それともメモリの使用が心配なのですか?

ほとんどのオブジェクトは短命です。したがって、メモリ管理とガベージコレクタは、短命のオブジェクトを効率的に処理するために構築されています。フレームワーク内の多くのクラスは、一度使用されるように設計されてから、より短命になるように破棄されます。

オブジェクトにハングアップしようとすると、ガベージコレクションに耐えられる可能性が高くなります。つまり、あるヒープの世代から別の世代に移動する可能性が高くなります。ヒープ世代は単なる論理的なオブジェクトの分割ではありませんが、オブジェクトは実際にはあるメモリ領域から別のメモリ領域に移動されます。ガベージコレクタは通常、ヒープ内のすべてのライブオブジェクトを次の世代に移動し、ヒープを空にするという原則で動作します。したがって、寿命の長いオブジェクトであり、寿命の短いオブジェクトではありません。

このデザインのため、実際のメモリ使用量は低いままですが、メモリスループットが高くなるのはかなり正常です。

+0

ワークロードが少し大きくなるとパフォーマンス上の問題が発生するため、一般的な領域を検査していましたが、UIスレッドの処理を外すことで解決しました。この記憶のことは、問題をプロファイリングするときに気づいたことの1つです。それは私が割り当てているように感じています。もっと重要なのは、これらの32KiBバッファが必要なときに、これらのバッファをすべてゼロにすることです。 –

2

DeflateStreamがDotNetZipにあり、事実上、.NET BCLに組み込まれているDeflateStreamが置き換えられています。 Ionic.Zlib.DeflateStreamには調整可能なバッファサイズがあります。私はそれがあなたのシナリオでより良いメモリ効率をもたらすかどうかわかりませんが、それは試してみる価値があるかもしれません。 Here's the doc

私は解凍をテストせず、むしろ圧縮しました。私のテストでは、私が圧縮したデータのサブセットのために、4kを超えてバッファサイズを拡大することで、限られたリターンを見出しました。一方、バッファが1024バイトであっても、有効ではありませんが、正確で正確な圧縮が得られます。私はあなたが減圧で同様の結果を見ると思います。

どちらの場合でも、ウィンドウサイズはパブリックインターフェイスから直接設定できません。しかし、それはオープンソースなので、デフォルトのWwindowサイズを適切に変更することは簡単にできます。また、貴重だと思えば、DeflateStreamの設定可能なパラメータとしてウィンドウサイズを公開するようリクエストすることができます。誰もそれを求めていないので、私はそれを公開していない。まだ?

あなたには他の圧縮もあります。 ZlibやGZipをやっているなら、DotNetZipパッケージにはZlibStreamとGZipStreamもあります。

Zipファイルを作成するには、完全なDotNetZipライブラリ(〜400kのIonic.Zip.dll)が必要です。あなたが{Deflate、Zlib、GZip} Streamをやっているだけなら、約90kのIonic.Zlib.dllがあります。

DotNetZipは無料ですが、donations are encouragedです。これをバックアップする任意の実際の測定の恩恵なし

+0

非常に興味深いですね。私はウィンドウのサイズを公開する必要はないと思うか良いアイデアです。問題は、私はたくさんの*と*を割り当てる必要があることです。この問題を攻撃するつもりなら、ストリームを新しいサブストリームで初期状態にリセットすることで解決します。 –

+0

ウィンドウサイズはzlib(C ilbrary)によって公開されています。そう前例のない。しかし、私が提供した抽象概念では、DeflateStreamの一部として公開していません。バッファのリサイクルに関しては、下位のZlibCodecクラスで確実に行うことができます。 IsはZlibエンコーダ/デコーダです。 DeflateStreamはその上に構築されます。ストリームとは対照的に、解凍するバッファがある場合は、ZlibCodecが使えます。 – Cheeso

+0

ps:ZlibCodecクラスを使用した場合、ウィンドウサイズも設定できます。 – Cheeso

関連する問題