数据集中的哪些特征会导致霍夫曼编码优于 Deflate 压缩?
我正在研究数字栅格数据集(例如陆地高程数据)的无损数据压缩。我发现在很多情况下,霍夫曼编码产生的输出比 Deflate 压缩要小。 我对这个结果有点惊讶,因为对于我过去查看的大多数数据来说,Deflate 比 Huffman 好很多
我正在使用 Deflate(6 级)的标准 Java API 和 Huffman 的自制版本。 我使用的技术在 https://gwlucastrig.github.io/GridfourDocs/notes/GridfourDataCompressionAlgorithms.html 中有描述。该实现压缩 11000 字节的块,并根据结果选择 Huffman 或 Deflate。 在大约 7700 例(36%)中选择了 Huffman,在大约 14000 例(64%)中选择了 Deflate。 我唯一的其他线索是,霍夫曼选择的块中的平均一阶熵是 5.83 位/符号,而 Deflate 选择的块中的平均一阶熵是 6.16 位/符号。
有关压缩测试的更多详细信息,请访问 https://gwlucastrig.github.io/GridfourDocs/notes/EntropyMetricForDataCompressionCaseStudies.html#method_selection
Huffman 无法超越 deflate 压缩数据格式,至少不会显着*,因为仅使用 Huffman 编码进行压缩是该格式的一个选项。
您的问题是关于 deflate 的具体实现。 Java 使用 zlib,它有一个关于如何利用 deflate 格式的 Huffman 编码和 LZ77 字符串匹配功能的策略。对于霍夫曼编码更好的情况,可能很少有字符串匹配,但有一些字符串匹配,这导致描述匹配代码的开销比从匹配中获得的开销更多。您使用的 deflate 实现不会尝试仅使用霍夫曼编码来查看是否会更小。 (虽然可以。我可能会补充一点。)
您可以尝试使用 deflate 仅使用 Huffman 与您的家庭烘焙版本进行比较。搜索
HUFFMAN_ONLY
这里。
*“霍夫曼编码”也不是单一的东西,而是包含一系列可能的实现。关键的变化是 a) 如何在霍夫曼编码数据之前发送霍夫曼编码的表示,b) 何时以及多久为后续数据的一定字节数创建一个新的霍夫曼编码,以及 c) 如何知道何时每组霍夫曼编码数据结束。这可能会导致不同数据的不同实现产生不同的性能。
对于a)有许多不同的方法来表示霍夫曼代码,其中一些比其他更紧凑。此外,使用规范的霍夫曼代码可以得到更小的描述,而编码数据中的位数没有变化。
对于b),某些数据的统计数据可能是同质的,因此新代码可能只会造成损害,而数据可能会以不同统计数据的形式出现,在这种情况下,压缩通常会受益于新代码。
对于c),添加“结束”符号是有效的,但在某些情况下会由于占用代码空间而减少压缩。预先添加计数可以避免这种情况,但专用计数位可能会使小块的情况变得更糟。
我假设这里的“霍夫曼编码”是指对数据字节进行霍夫曼编码,因此有 256 个可能的符号。您还可以尝试编码 65536 个符号,其中前一个字节预测下一个字节。现在我们正在研究数据的高阶模型。