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

问题描述 投票:0回答:1

在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;
}
compression zlib deflate gz
1个回答
3
投票

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

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

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

这是重复的,因此如果您正在为小输入缓冲区提供压缩数据,则压缩数据似乎将以突发形式提供。它与大输入缓冲区完全相同,但是你只是没有看到延迟,但它仍然存在。

© www.soinside.com 2019 - 2024. All rights reserved.