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:为啥它会累积短数据并且直到输入缓冲区已满才开始压缩?的主要内容,如果未能解决你的问题,请参考以下文章

zlib-Deflate压缩算法

zlib-Deflate压缩算法

使用DEFLATE(RFC 1951)函数压缩和解压缩zlib(RFC 1950)

Linux(程序设计):29---Zlib库(数据压缩与解压)

Swoole WebSoctet 使用 zlib 压缩之 PHP 与 pako.js

数据流压缩之应用篇zlib库