这是一个奇怪的情况。我知道真正的解决方案是潜入开源并修复错误。但请幽默我......
我正在使用GELF标准将日志消息发送到logstash
(版本5.0.0)。可悲的是,logstash
的GELF解析器(Ruby gem gelfd:0.2.0
)can only parse compressed messages。
对我来说阻力最小的路径就是压缩我的每条日志消息。即使它是一个100字节的消息。没有任何有意义的大小优势(无论哪种方式适合单个UDP数据报,其目的地是localhost),实际上文件may become larger。
我担心我的应用程序会执行大量不必要的压缩 - 而我的logstash
服务器会执行大量不必要的解压缩 - 只是为了解决gelfd
中的这个错误。
compression algorithms supported by GELF是GZIP和ZLIB。
使用这些算法:尝试压缩然后解压缩一个小文件的计算成本有多大?
修改:对于提交此问题而不做我自己的任何研究表示抱歉。忏悔:我现在提交了自己的基准测试结果作为答案。
答案 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编写了一个基准测试脚本。
这不完全具有代表性:
然而,它提供了一个有用的启发式方法。
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可执行文件的启动和清理成本。我不确定这些是否重要,但我们当然可以看到它是一个线程化的应用程序(用户+ sys< real)。所以我可以想象设置开销,例如启动pthreads。
我无法找到关于GZIP的时间复杂度与输入大小相关的任何结论性答案。但要知道它会很有趣。