小4 KB文件的最佳压缩算法是什么?

时间:2009-04-09 02:33:06

标签: compression

我正在尝试压缩每个大约4 KB的TCP数据包。数据包可以包含任何字节(从0到255)。我发现的压缩算法的所有基准都是基于更大的文件。我没有找到任何比较小文件上不同算法的压缩比的东西,这就是我需要的。我需要它是开源的,所以它可以在C ++上实现,所以没有例如RAR。对于大小约4千字节的小文件,可以推荐什么算法? LZMAHACCZIPgzipbzip2

10 个答案:

答案 0 :(得分:13)

选择最快的算法,因为您可能关心实时这样做。通常对于较小的数据块,算法压缩大致相同(给出或占用几个字节),主要是因为除了有效载荷之外,算法还需要传输字典或霍夫曼树。

我强烈推荐Deflate(由zlib和Zip使用)有很多原因。该算法非常快,经过良好测试,获得BSD许可,并且是Zip支持的唯一压缩(根据infozip Appnote)。除了基础知识,当它确定压缩大于解压缩大小时,存在一个STORE模式,它只为每个数据块增加5个字节(最大块为64k字节)。除了STORE模式,Deflate支持两种不同类型的霍夫曼表(或词典):动态和固定。动态表意味着霍夫曼树作为压缩数据的一部分被传输,并且是最灵活的(用于不同类型的非随机数据)。固定表的优点是该表是所有解码器都知道的,因此不需要包含在压缩流中。解压缩(或Inflate)代码相对容易。我直接编写了基于zlib的Java和Javascript版本,它们的表现相当不错。

提到的其他压缩算法有其优点。我更喜欢Deflate,因为它在压缩步骤和特别是在解压缩步骤中都具有运行时性能。

澄清一点:Zip不是压缩类型,它是一个容器。为了进行数据包压缩,我会绕过Zip,只使用zlib提供的deflate / inflate API。

答案 1 :(得分:5)

答案 2 :(得分:2)

所有这些算法都是合理的尝试。正如您所说,它们并未针对微小文件进行优化,但您的下一步就是尝试它们。测试压缩一些典型的数据包可能只需要10分钟,并查看结果的大小。 (尝试不同的压缩标志)。从生成的文件中,您可以找出最适合的工具。

你列出的候选人都是第一次尝试。您也可以尝试bzip2。

有些简单的“全部尝试”是一个很好的解决方案,当测试很容易做到时...思考太多有时会让你失望。

答案 3 :(得分:2)

Compression of ASCII messages scatter plot

这是我所推荐的Rick出色回答的后续措施。不幸的是,我无法在评论中添加图片。

我遇到了这个问题,决定尝试对500个ASCII消息的样本进行压缩,该消息的大小从6到340字节不等。每条消息都是由环境监控系统生成的一点数据,该系统通过昂贵的(按字节收费)卫星链路进行传输。

最有趣的发现是,压缩后消息较小的交叉点与生命,宇宙和一切的终极问题相同:42个字节。 / p>

要对您自己的数据进行尝试,这里有一些node.js可以帮助您:

const zlib = require('zlib')
const sprintf = require('sprintf-js').sprintf
const inflate_len = data_packet.length
const deflate_len = zlib.deflateRawSync(data_packet).length
const delta = +((inflate_len - deflate_len)/-inflate_len * 100).toFixed(0)
console.log(`inflated,deflated,delta(%)`)
console.log(sprintf(`%03i,%03i,%3i`, inflate_len, deflate_len, delta))

答案 4 :(得分:1)

我不认为文件大小很重要 - 如果我没记错的话,GIF中的LZW会每隔4K重置一次字典。

答案 5 :(得分:1)

ZLIB应该没问题。它用于MCCP。

但是,如果你真的需要良好的压缩,我会对常见模式进行分析,并在客户端中包含它们的字典,这样可以产生更高级别的压缩。

答案 6 :(得分:1)

我很幸运直接使用zlib压缩库而不使用任何文件容器。 ZIP,RAR,存储文件名之类的开销。我已经看到压缩这种方式对于低至200字节的数据包产生正结果(压缩小于原始大小)。

答案 7 :(得分:1)

您可以测试bicom。 禁止该算法用于商业用途。 如果您想将它用于专业或商业用途,请查看“范围编码算法”。

答案 8 :(得分:0)

您可以尝试delta compression。压缩取决于您的数据。如果您对有效负载有任何封装,那么您可以压缩标头。

答案 9 :(得分:-3)

我做了Arno Setagaya在他的回答中提出的建议:做了一些样本测试并比较了结果。

压缩测试使用5个文件完成,每个文件大小为4096字节。这5个文件中的每个字节都是随机生成的。

重要提示:在现实生活中,数据不太可能是随机的,但往往会有一些重复的字节。因此,在现实生活中,压缩会比以下结果更好一些。

注意:5个文件中的每一个都是自己压缩的(即不与其他4个文件一起压缩,这会导致更好的压缩)。在下面的结果中,为简单起见,我只使用5个文件大小的总和。

我之所以加入RAR只是出于比较原因,即使它不是开源的。

结果:(从最佳到最差)

LZOP:20775/20480 * 100 =原始大小的101.44%

RAR:20825/20480 * 100 =原始大小的101.68%

LZMA:20827/20480 * 100 =原始尺寸的101.69%

ZIP:21020/20480 * 100 =原始尺寸的102.64%

BZIP:22899/20480 * 100 =原始大小的111.81%

结论:令我惊讶的是,所有测试的算法都产生了比原件更大的尺寸!我猜它们只适用于压缩较大的文件,或者具有大量重复字节的文件(不是像上面那样的随机数据)。因此,我不会在TCP数据包上使用任何类型的压缩。也许这些信息对于考虑压缩小块数据的其他人有用。

编辑: 我忘了提到我为每个算法使用了默认选项(标志)。