zlib deflate:为什么它会累积短数据并且在输入缓冲区已满之前不会开始压缩?

时间:2018-03-01 19:54:20

标签: compression zlib deflate gz

在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 个答案:

答案 0 :(得分:3)

deflate压缩数据格式由块组成,块具有取决于块数据的标头。因此,deflate的输出一次出现一个块,在第一个块完成之前没有写入任何内容(zlib或gzip头除外)。

zlib的deflate累积数据,直到默认设置已生成16K符号。符号是单个字节,编码为文字,或长度/距离对,它在前面的32K未压缩数据中的某处编码最多258个字节的副本。因此,在发出第一个块之前,您将从16K累积到多达4MB的未压缩数据(对于高度可压缩的数据)。

一旦该数据被累积,zlib决定构造哪种块,然后这样做,创建标题,对于动态块描述块中的霍夫曼码,然后为该块创建编码符号。或者它创建一个存储或静态块,无论以最少的位数产生什么结果。只有这样才能获得压缩数据。

这是重复的,因此如果你给它输入小的输入缓冲区,那么deflate压缩数据似乎会以突发形式出现。它与大输入缓冲区完全相同,但是你只是没有看到延迟,但它仍然存在。