Java Deflater で言及されている戦略オプションは、ZLIB および ( RFC 1950 ) および DEFLATE ( 1951 ) の zlib (C) 実装に由来すると私は信じています。これらは、DEFLATE を実装する事実上すべての圧縮ライブラリに存在します。
それらの意味を理解するには、 DEFLATEについて少し知っておく必要があります。圧縮アルゴリズムは、LZ77 とハフマン コーディングを組み合わせたものです。基本は次のとおりです。
LZ77 圧縮は、繰り返される一連のデータを見つけることによって機能します。実装では通常、1k から 32k の間の「スライディング ウィンドウ」を使用して、以前のデータを追跡します。元のデータの繰り返しについては、出力に繰り返しデータを挿入する代わりに、LZ77 圧縮は「後方参照」を挿入します。「ここに、8293 バイト前に見たのと同じデータを 17 バイト挿入する」という後方参照を想像してみてください。back-ref は、この数値のペアとしてエンコードされます: 長さ (この場合は 17) と距離 (またはオフセット) (この場合は 8293)。
ハフマン コーディングは、実際のデータの代わりにコードを使用します。データが X の場合、ハフマン コードは Y を示します。これは明らかに、代替が元のコードよりも短い場合にのみ圧縮に役立ちます。(反例は、ジム・キャリーの映画「Yes Man」で、Norm が Carl の短縮名に「Car」を使用する場合です。Carl は、Carl はすでにかなり短いと指摘しています。) ハフマン符号化アルゴリズムは周波数分析を行い、最短の最も頻繁に発生するデータ シーケンスを置き換えます。
Deflate はこれらを組み合わせて、LZ77 後方参照でハフマン コードを使用できるようにします。さまざまな DEFLATE/ZLIB コンプレッサーの戦略オプションは、LZ77 に対して Huffman をどれだけ重み付けするかをライブラリーに指示するだけです。
( zlib の man ページから)
...コードを読んだところ、LZ77 マッチングを行うと書かれていますが、最大 5 バイト以下のシーケンスに限られます。それが、私が推測する「小さな値」によってドキュメントが意味するものです。しかし、数値 5 はドキュメントに記載されていないため、数値が rev から rev へ、または ZLIB/DEFLATE のある実装から別の実装 (C バージョンや Java バージョンなど) に変更されないという保証はありません。
HUFFMAN_ONLY
は、周波数分析に基づいて置換コードのみを実行します。 HUFFMAN_ONLY
非常に高速ですが、ほとんどのデータの圧縮にはあまり効果的ではありません。バイト値の範囲が非常に狭い場合 (たとえば、実際のデータ ストリームのバイトが可能な 255 の値のうち 20 の値のいずれかを取る場合)、またはサイズを犠牲にして圧縮速度の極端な要件HUFFMAN_ONLY
がない限り、あなたがしたい。
DEFAULT
ほとんどのアプリケーションで最も効果的であると著者が予想した方法で 2 つを組み合わせます。
私の知る限り、DEFLATE 内で LZ77 だけを行う方法はありません。LZ77_ONLY
戦略はありません。もちろん、独自の LZ77 エンコーダーを構築または取得することもできますが、それは「LZ77 のみ」になります。
戦略が圧縮の正確さに影響を与えることはないことに注意してください。速度またはサイズのいずれかでのみ、その操作とパフォーマンスに影響します。
コンプレッサーを調整する方法は他にもあります。1 つは、LZ77 スライド ウィンドウのサイズを設定することです。C ライブラリでは、これは「ウィンドウ ビット」オプションで指定されます。LZ77 を理解している場合は、ウィンドウが小さいほど後方検索が少なくなるため、圧縮が高速になりますが、一部の一致が失われるという犠牲を払うことがわかります。多くの場合、これはコンプレッション時に回すのがより効果的なノブです。
要するに、80% のケースでは、戦略を微調整する必要はありません。何が起こるかを見るためだけに、ウィンドウ ビットをいじることに興味があるかもしれません。ただし、アプリで行う必要がある他のすべてのことを行った場合にのみ、それを行ってください。
参照:
Antaeus Feldspar による DEFLATE の仕組み