gpt4 book ai didi

linux - 为什么 gnu 并行分块会提高 gzip 的压缩大小?

转载 作者:IT王子 更新时间:2023-10-29 00:20:20 24 4
gpt4 key购买 nike

文件位于:“意外效率部门”。

前 9000 万个数字占用约 761MB,输出为:

 seq 90000000

根据 man parallel,它可以加速 gzip 的归档大文件,方法是将输入切碎,并使用不同的 CPU 来压缩 block 。因此,尽管 gzip单线程,但这项技术使其成为多线程:

seq 90000000  | parallel --pipe --recend '' -k gzip -9 >bigfile.gz

在 Intel Core i3-2330M (4) @ 2.2GHz 上耗时 46 秒。

将其通过管道传输到普通的旧 gzip:

seq 90000000  | gzip -9 > bigfile2.gz

在同一个 CPU 上耗时 80 秒。现在是惊喜:

ls -log bigfile*.gz

输出:

-rw-rw-r-- 1 200016306 Jul  3 17:27 bigfile.gz
-rw-rw-r-- 1 200381681 Jul 3 17:30 bigfile2.gz

300K 更大?那看起来不对劲。首先,我检查了 zdiff 文件是否具有相同的内容——是的,相同。我原以为任何压缩器在处理连续数据流时会比分 block 压缩器做得更好。为什么 bigfile2.gz 不小于 bigfile.gz

最佳答案

原因是对于这个特殊的、相当不寻常的输入,较小的放气 block 比较大的放气 block 更好。默认情况下,gzip 使用较大的 deflate block ,因为它最适合普通输入数据。 parallel 命令通过每 1 MB 分解输入来强制使用一些较小的压缩 block ,从而产生较小的增益。尽管大多数 block 的大小仍然相同。

通过使用 zlib每个 block 设置较小的 block 大小可以做得更好deflateInit2() 中的 memLevel 参数。在这里,我每次都在单个线程中压缩相同的输出,使用从 9 到 2 的 memLevel 值,其中较小的 memLevel 是较小的放气 block 大小(请注意 zlib在默认级别比您的 gzip 好一点):

  • 9 - 199688429
  • 8 - 198554111(默认)
  • 7 - 191582070
  • 6 - 184880482
  • 5 - 181295029
  • 4 - 180137425(此输入的最佳值)
  • 3 - 181176610
  • 2 - 185759115

此数据的最佳 memLevel 结果为 4,压缩后的数据比默认 memLevel 8 小 12 MB (9%)。对于 memLevel 8,deflate block 大小为 16383 个符号,而对于 memLevel 4,deflate block 大小为 1023 个符号。一个符号是文字字节或匹配项。

改进来自输入的极其规则的性质,导致匹配和文字命令的规则序列。 block 大小越小,出现的这种不同的命令就越少,然后需要更少的比特来对它们中的每一个进行编码。这对于 memLevel 3 仍然适用,但到那时每个 deflate block 开头的代码描述的开销抵消了更少不同代码的改进。

zopfli是一个 deflate 压缩器,可以优化 block 大小和所选命令,并设法将其压缩到 100,656,812 字节。虽然花了三个半小时! zopfli 被调用 pigz使用压缩级别 11。

关于linux - 为什么 gnu 并行分块会提高 gzip 的压缩大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38178734/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com