事前に圧縮されたデータを挿入できる圧縮ストリームを圧縮します。 .NETライブラリは存在しますか?
-
05-07-2019 - |
質問
WebコンテンツにDeflateおよびGZip圧縮を実装しています。 .NET Framework DeflateStreamのパフォーマンスは非常に良好です(SharpZipLibほど優れた圧縮は行いませんが、はるかに高速です)。残念ながら、それ(および私が知っている他のすべてのライブラリ)は、stream.WritePrecompressed(byte [] buffer)のような事前に圧縮されたデータを書き込む関数を失います。
この関数を使用すると、事前に圧縮されたブロックをストリームに挿入できます。これにより、この部分を圧縮するためのCPU負荷が削減され、Webサーバーの合計スループットが増加します。
これを実行できるマネージライブラリはありますか?または、ComponentAceのZLIB.NETを超えてこれを行うための良い出発点はありますか?
解決
別のアプローチは、デフレーターストリームをフラッシュし(場合によっては閉じる)、すべてのバッファリングされた圧縮データが出力ストリームに書き込まれることを保証し、基本圧縮ストリームを単純に基本出力ストリームに書き込み、再度開くことです出力ストリームの上にデフレーターストリームを再度追加します。
他のヒント
IIRC #ZipLibを使用すると、圧縮レベルを設定できます。ストリームをフラッシュしてレベルを0に落とし、圧縮レベルを再度上げる前にすでに圧縮されたデータを送信しようとしましたか?
パフォーマンス上の理由でこれを行うことのみを検討している場合、これは許容できる解決策である可能性があります。
はい、事前に圧縮されたブロックをzlibストリームに挿入できます。 zlibソースのzpipe.cの例から始めます。事前に圧縮されたブロックを挿入する場所でのみ、Z_NO_FLUSHをZ_FULL_FLUSHに置き換えます(圧縮率が低下するため、Z_FULL_FLUSHは使用しないでください)。
圧縮された出力はバイト単位で整列され、最後のdeflateブロックが閉じられます。完全フラッシュとは、事前に圧縮されたブロックの次のブロックに後方参照を含めることができないことを意味します。
事前に圧縮されたブロックを出力ストリームに追加します(例:memcpy)。 strm.next_outを次の空のバイトに進めます。中断したところから収縮を続けます。
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
ret = deflate(&strm, flush);