估计 DEFLATE 的(zlib)当前压缩大小的方法,无需刷新

Method of estimating DEFLATE's (zlib) current compressed size without flush

我目前正在编写一个接受高速缓存行(64 字节,但可调整)的程序,并尝试将尽可能多的内容放入 512 字节块(同样可调整)。

问题是我需要能够在每次调用 deflate 而不刷新后至少粗略估计当前的压缩大小。每个字节对我的目的都很重要,刷新会根据数据增加非常大的开销,尤其是考虑到我使用的块大小很小。我用 Z_SYNC_FLUSH 和 Z_PARTIAL_FLUSH 尝试了各种不同的实现,但两者都增加了很多开销以始终有用。

我目前天真的方法是压缩 9 个缓存行(576 字节)并检查它是否适合 512 块,如果适合则添加另一个缓存行并重新压缩整个缓冲区等等。如果前 9 个缓存行无法放入 512 块,则它只是未压缩存储(原始未压缩)。

你可以想象这种方法需要很长时间,用这种方法压缩一个 7GB 的文件需要将近 3 个小时。

我注意到 z_stream 结构有一个我可以公开的内部状态,但我没有找到任何明显的方法来利用它来获得估计。我认为这是因为在冲洗之前没有实际发生压缩。

有没有办法在实际刷新之前获得压缩输出的估计大小? 如果没有,我能做些什么来减少我当前方法的时间开销吗?

查看 fitblk.c 了解一种方法。它的开销大约是原来的三倍,因为它对每个块进行三次压缩。

基本思想是首先压缩到足以溢出所需的块。然后解压缩,直到您处理适合所需块的压缩数据量,然后仅压缩该块。第二遍改进了拟合度。