流压缩能力如何影响压缩算法?

4
我最近通过将其作为tar流发送并在我的计算机上压缩来备份即将到期的大学主目录:ssh user@host "tar cf - my_dir/" | bzip2 > uni_backup.tar.bz2
这让我想到了一些问题:虽然我只知道压缩的基础知识,但我认为这种压缩数据流的能力会导致较差的压缩效果,因为算法需要在某个点完成处理一个数据块,将其写入输出流并继续到下一个块。
这是真的吗?还是这些程序只是读取大量数据到内存中进行压缩,然后写入,再重复此过程?或者这些“流压缩程序”使用了一些巧妙的技巧?我看到bzip2xz的手册页面都提到了内存使用情况,bzip2的手册页面还暗示了将要压缩的数据切分成块时很少会有损失:
“较大的块大小会导致迅速递减的边际回报。大部分压缩来自块大小的前两三百k,这一事实值得在小型机器上使用bzip2时注意。同样重要的是要认识到,在压缩时选择块大小会设置解压缩的内存需求。”
我仍然很想知道是否使用了其他技巧,或者在哪里可以阅读更多相关内容。

2
好问题;我只想指出,将数据流通过诸如bzip2这样的压缩程序进行传输,并不意味着小块数据会实时被压缩和发送。你可以轻松地使用一个压缩工具来接收所有发送到它的数据,直到达到文件尾(EOF)为止,然后再进行压缩并发送。 - Rag
1
我不会期望 bzip2 在开始写入输出的第一个字节之前分析数千兆字节的数据。这可能会在最终大小上节省一些字节,但我们也想要性能。不过,是的,我也喜欢你的问题。 - Christopher Creutzig
1个回答

7
这个问题与缓冲区处理相关,而不是压缩算法,尽管也可以谈一些相关内容。
一些压缩算法固有地是“基于块”的,这意味着它们绝对需要使用特定大小的块进行工作。这就是bzip2的情况,其块大小是通过“级别”开关选择的,从100kb到900kb不等。因此,如果你将数据流式传输到它中,它会等待块被填满,并在块填满后开始压缩该块(或者,对于最后一个块,它将使用接收到的任何大小进行压缩)。
一些其他的压缩算法可以处理流,这意味着它们可以使用保留在内存缓冲区中的旧数据持续压缩新数据。基于“滑动窗口”的算法可以胜任这项任务,通常zlib能够实现这一点。
即便如此,“滑动窗口”压缩器仍然可能选择将输入数据切割成块,以便更轻松地管理缓冲区,或是为了开发多线程功能,例如pigz。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接