使用压缩和放大器有多贵?微小有效载荷上的解压缩(<100bytes)?

时间:2016-11-09 20:39:32

标签: compression

这是一个奇怪的情况。我知道真正的解决方案是潜入开源并修复错误。但请幽默我......

我正在使用GELF标准将日志消息发送到logstash(版本5.0.0)。可悲的是,logstash的GELF解析器(Ruby gem gelfd:0.2.0can only parse compressed messages

对我来说阻力最小的路径就是压缩我的每条日志消息。即使它是一个100字节的消息。没有任何有意义的大小优势(无论哪种方式适合单个UDP数据报,其目的地是localhost),实际上文件may become larger

我担心我的应用程序会执行大量不必要的压缩 - 而我的logstash服务器会执行大量不必要的解压缩 - 只是为了解决gelfd中的这个错误。

compression algorithms supported by GELF是GZIP和ZLIB。

使用这些算法:尝试压缩然后解压缩一个小文件的计算成本有多大?

修改:对于提交此问题而不做我自己的任何研究表示抱歉。忏悔:我现在提交了自己的基准测试结果作为答案。

2 个答案:

答案 0 :(得分:2)

您无需实际压缩即可生成有效的zlib或gzip流。两者使用的deflate压缩数据格式具有不可压缩数据的存储模式。您甚至无需使用zlib即可轻松编写此格式。虽然您仍然希望使用zlib中的完整性检查例程,例如adler32()用于zlib格式,或crc32()用于gzip格式。

zlib标头可以是0x78 0x01。然后编写由00组成的存储块,然后是小字节顺序的两字节长度,然后是相同的两个字节但它们的一个补码,然后是存储数据的长度字节。最后存储的块以01而不是00开头。然后使用Adler-32检查未压缩数据,以big-endian顺序检查四个字节。完成。

示例有效的zlib流编码123456789,格式为十六进制:

78 01 01 09 00 f6 ff 31 32 33 34 35 36 37 38 39 09 1e 01 de

答案 1 :(得分:1)

我为GZIP编写了一个基准测试脚本。

这不完全具有代表性:

  • 不使用与Java程序将使用的完全相同的压缩器/解压缩器实现
  • 不在与Java程序完全相同的运行时条件下运行
  • 不测试各种字符串
  • 不测试各种字符串大小

然而,它提供了一个有用的启发式方法。

plain="2016-11-09 20:56:02,469 ERROR [main] c.s.HelloExample - Something wrong with customer 'CUS-123e4567-e89b-12d3-a456-42665544'"

echo "Log message which we are using for this test is:"
echo $plain

echo "Time taken to echo this string 10,000 times:"

time for a in $(seq 1 10000);
do
    echo $plain > /dev/null
done

echo "Time taken to echo and compress this string 10,000 times:"

time for a in $(seq 1 10000);
do
    echo $plain | gzip -cf > /dev/null
done

echo "Time taken to echo, compress and decompress this string 10,000 times:"

time for a in $(seq 1 10000);
do
    echo $plain | gzip -cf | gzip -cfd > /dev/null
done

测量结果如下:

Log message which we are using for this test is:
2016-11-09 20:56:02,469 ERROR [main] c.s.HelloExample - Something wrong with customer 'CUS-123e4567-e89b-12d3-a456-42665544'
Time taken to echo this string 10,000 times:

real    0m1.940s
user    0m0.591s
sys 0m1.333s
user+sys 0m1.924s
Time taken to echo and compress this string 10,000 times:

real    0m22.028s
user    0m11.309s
sys 0m17.325s
user+sys 0m28.634s
Time taken to echo, compress and decompress this string 10,000 times:

real    0m22.983s
user    0m18.761s
sys 0m27.322s
user+sys 0m46.083s
[Finished in 47.0s real time]

User+sys shows how much CPU time was used;这对于弄清楚计算密集程度是多么重要。

因此,压缩比仅回显字符串raw需要大约14.9倍的计算量。

压缩+解压缩比仅回显字符串raw需要多24.0倍的计算量。这比压缩计算量多1.6倍。

结论:

  • 在GZIP中压缩一个小文件并不便宜。
  • GZIP减压很便宜!

警告:实际上,此测试可能已经测量了gzip可执行文件的启动和清理成本。我不确定这些是否重要,但我们当然可以看到它是一个线程化的应用程序(用户+ sys&lt; real)。所以我可以想象设置开销,例如启动pthreads。

我无法找到关于GZIP的时间复杂度与输入大小相关的任何结论性答案。但要知道它会很有趣。