Java Deflater策略 - DEFAULT_STRATEGY,FILTERED和HUFFMAN_ONLY

Key*_*yur 5 java compression gzip deflate

我试图在gzipping Java webapp响应时找到性能和压缩程度之间的平衡.

在查看Deflater类时,我可以设置一个级别和策略.水平不言自明- BEST_SPEEDBEST_COMPRESSION.

我不知道关于战略- DEFAULT_STRATEGY,FILTEREDHUFFMAN_ONLY

我可以从Javadoc中获得一些意义,但我想知道是否有人在他们的应用程序中使用了特定策略,并且您是否看到在性能/压缩程度方面存在任何差异.

Che*_*eso 14

Java Deflater中提到的策略选项起源于ZLIB(RFC 1950)和DEFLATE(1951)的zlib(C)实现,我相信.它们几乎存在于实现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编码算法进行频率分析,并使用最短的替代最常出现的数据序列.


Deflate结合了这些,因此可以在LZ77反向引用上使用霍夫曼代码.各种DEFLATE/ZLIB压缩机的策略选项只是告诉图书馆对Huffman和LZ77的重量是多少.

  • FILTERED 通常意味着LZ77匹配停止在5的长度.所以当文档说

    使用(过滤)过滤器(或预测器)生成的数据,...过滤后的数据主要由具有某种随机分布的小值组成.

    (来自zlib手册页)
    ...我对代码的读取表明它与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%的情况,您并不关心调整策略.您可能对摆弄窗口位感兴趣,只是为了看看会发生什么.但只有当你完成了在应用程序中需要做的其他事情时才这样做.


参考:
Antaeus Feldspar如何使用DEFLATE