zlib deflate:为什么它会累积短数据并且直到输入缓冲区已满才开始压缩?

zlib deflate: why does it accumulate short data and doesn't start compression until input buffer is full?

在zlib的deflate实现中,注意到当给定的数据长度较小时,zlib函数会将数据复制到输入缓冲区,只有当输入缓冲区已满时才开始压缩。

当给定数据的长度大于输入缓冲区大小时,zlib 函数直接开始压缩。

默认输入缓冲区大小为 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;
}

deflate 压缩数据格式由块组成,块具有依赖于块数据的header。因此 deflate 的输出一次一个块,在第一个块完成之前什么都不写(除了 zlib 或 gzip header)。

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

一旦积累了数据,zlib 就会决定构建什么样的块,然后创建 header,对于动态块,它描述块中的霍夫曼代码,然后创建该块的编码符号。或者它创建一个存储的或静态的块,无论结果是最少的位数。只有这样压缩数据才可用。

这会重复进行,因此如果您向其提供较小的输入缓冲区,则 deflate 压缩数据将以突发形式出现。它对大输入缓冲区做完全相同的事情,但你只是看不到延迟,但它仍然存在。