2010-03-26 46 views
5

我試圖在gzipping Java webapp響應時在性能和壓縮程度之間找到平衡點。Java Deflater策略 - DEFAULT_STRATEGY,FILTERED和HUFFMAN_ONLY

在研究Deflater類時,我可以設置一個級別和一個策略。水平是自我解釋 - BEST_SPEEDBEST_COMPRESSION

我不知道關於戰略 - DEFAULT_STRATEGYFILTEREDHUFFMAN_ONLY

我可以從的Javadoc一定意義,但我不知道是否有人在他們的應用程序中使用特定的策略,如果你看到任何區別就性能/壓縮程度而言。

回答

14

Java Deflater中提到的策略選項起源於ZLIB的zlib(C)實現,並且(RFC 1950)和DEFLATE(1951),我相信。它們幾乎存在於實現DEFLATE的所有壓縮庫中。

要理解它們的含義,您需要了解一些關於DEFLATE的信息。壓縮算法結合了LZ77和霍夫曼編碼。基本的是:

  • LZ77壓縮通過查找重複的數據序列來工作。實現通常使用1k和32k之間的「滑動窗口」來跟蹤以前的數據。對於原始數據中的任何重複,而不是在輸出中插入重複的數據,LZ77壓縮會插入一個「反向參考」。想象一下後面的參考文字說「在這裏,插入8293字節前看到的相同數據,17個字節」。 back-ref編碼爲這一對數字:一個長度(在本例中爲17)和一個距離(或偏移量) - 在本例中爲8293.

  • 霍夫曼編碼替代編碼爲實際數據編碼。當數據表示X時,霍夫曼代碼表示Y.只有當替代品比原來短時,這顯然有助於壓縮。 (反例如Jim Carrey的電影Yes Man,Norm使用「Car」作爲Carl的簡稱,Carl指出Carl已經很矮了)。Huffman編碼算法進行頻率分析,並使用最短的替代品用於最經常出現的數據序列。


放氣組合這些,讓人們可以在LZ77背裁判使用霍夫曼碼。各種DEFLATE/ZLIB壓縮機的策略選項只是告訴圖書館Huffman與LZ77相比有多重要。

  • FILTERED通常意味着LZ77比賽是在爲5的長度停止所以,當文檔說

    使用(已過濾的),用於通過一個過濾器(或預測)產生的數據,...經過濾的數據主要由小的值組成,並且分佈有些隨機。

    (從the zlib man page
    ...我的代碼讀取說,它確實LZ77匹配,但最多隻能爲5個或更少的字節序列。我猜這就是文檔所說的「小值」。但是數字5在文檔中沒有提及,所以不能保證數字不會從rev到rev,或者從ZLIB/DEFLATE的一個實現改變到另一個(如C版本和Java版本)。

  • HUFFMAN_ONLY說,只做基於頻率分析的替代代碼。 HUFFMAN_ONLY速度非常快,但對大多數數據的壓縮效果不是很好。除非您的字節值範圍非常小(例如,如果實際數據流中的字節數僅爲可能的255個值中的20個值中的一個),或者對壓縮速度有極大的要求,但代價是大小,HUFFMAN_ONLY將不會你想要什麼。

  • DEFAULT將兩者結合在一起,作者認爲這對大多數應用來說是最有效的。


據我所知,中DEFLATE是沒有辦法做到只LZ77。沒有LZ77_ONLY策略。但是,當然你可以建立或者購買你自己的LZ77編碼器,那將是「僅LZ77」。


請記住,策略不會影響正確的壓縮;它隻影響和操作它,以及它的速度或大小。


還有其他的方法來調整壓縮機。一個是設置LZ77滑動窗口的大小。在C庫中,這是用「窗口位」選項指定的。如果你理解LZ77,那麼你知道一個更小的窗口意味着更少的搜索回來,這意味着更快的壓縮,但是會漏掉一些匹配。壓縮時這通常是更有效的旋鈕。


底線是,對於80%的情況下,你不小心調整策略。您可能有興趣擺弄窗口位,只是爲了看看會發生什麼。但只有當你完成了你需要在你的應用程序中完成的其他事情時才這樣做。


參考:
How DEFLATE works, by Antaeus Feldspar