zlib deflate:为啥它会累积短数据并且直到输入缓冲区已满才开始压缩?
Posted
技术标签:
【中文标题】zlib deflate:为啥它会累积短数据并且直到输入缓冲区已满才开始压缩?【英文标题】:zlib deflate: why does it accumulate short data and doesn't start compression until input buffer is full?zlib deflate:为什么它会累积短数据并且直到输入缓冲区已满才开始压缩? 【发布时间】:2018-03-01 19:54:20 【问题描述】:在zlib的deflate实现中,注意到当给定的数据长度较小时,zlib函数会将数据复制到输入缓冲区,只有在输入缓冲区满时才开始压缩。
当给定数据的长度大于输入缓冲区大小时,zlib 函数直接开始压缩。
默认输入缓冲区大小为 8KB。
我想知道将短数据累积到输入缓冲区的好处。我能想到的是:
避免花费在块处理上的开销,包括 Huffman 树初始化和 CRC 计算 保持 I/O 在 8KB(或更大)块上工作,有利于性能知道更多见解的人可以与我分享您的想法,或者给我一些参考吗?
相关代码:
if (len < state->size)
/* copy to input buffer, compress when full */
do
if (strm->avail_in == 0)
strm->next_in = state->in;
n = state->size - strm->avail_in;
if (n > len)
n = len;
memcpy(strm->next_in + strm->avail_in, buf, n);
strm->avail_in += n;
state->x.pos += n;
buf = (char *)buf + n;
len -= n;
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
while (len);
else
/* consume whatever's left in the input buffer */
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
/* directly compress user buffer to file */
strm->avail_in = len;
strm->next_in = (voidp)buf;
state->x.pos += len;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
【问题讨论】:
【参考方案1】:deflate 压缩数据格式由块组成,块具有依赖于块数据的标头。因此,deflate 的输出一次出现一个块,在第一个块完成之前没有写入任何内容(除了 zlib 或 gzip 标头)。
zlib 的 deflate 会累积数据,直到默认设置已生成 16K 个符号。符号可以是单个字节,编码为文字,也可以是长度/距离对,在前面的 32K 未压缩数据中的某处编码最多 258 个字节的副本。因此,在发出第一个块之前,您将累积从 16K 到多达 4MB 的未压缩数据(对于高度可压缩的数据)。
一旦数据被积累,zlib 决定构建什么样的块,然后这样做,创建标题,用于动态块描述块中的霍夫曼代码,然后为该块创建编码符号。或者它创建一个存储或静态块,无论导致最少的位数。只有这样,压缩数据才可用。
这是重复的,因此如果您向其提供小的输入缓冲区,则 deflate 压缩数据将显示为突发可用。它对大型输入缓冲区执行完全相同的操作,但是您并没有那么容易看到延迟,但它仍然存在。
【讨论】:
以上是关于zlib deflate:为啥它会累积短数据并且直到输入缓冲区已满才开始压缩?的主要内容,如果未能解决你的问题,请参考以下文章
使用DEFLATE(RFC 1951)函数压缩和解压缩zlib(RFC 1950)
Linux(程序设计):29---Zlib库(数据压缩与解压)