GZIP压缩级别对解压有影响吗?

68
我了解到GZIP是LZ77和Huffman编码的组合,并且可以配置1-9级别,其中1表示最快的压缩(较少的压缩),9表示最慢的压缩方法(最佳压缩)。
我的问题是,级别的选择只影响压缩过程吗?还是在解压缩时也会产生额外的成本,具体取决于用于压缩的级别?
我之所以问这个问题,是因为通常许多Web服务器会在客户端支持时即时压缩响应,例如Accept-Encoding: gzip。我很欣赏,在实时压缩时,像6这样的级别可能是平均情况下的好选择,因为它在速度和压缩之间取得了良好的平衡。
但是,如果我有一堆静态资产可以预先进行GZIP压缩,并且永远不需要再次进行此操作,则使用最高但最慢的压缩级别是否会有任何不利影响?也就是说,现在对于客户端是否存在额外的开销,如果使用较低的压缩级别将不会产生这种开销。

虽然下面的答案提供的数据可能是当今实际使用的准确数据,但这里还有一些补充点。首先,我对zlib(包括gzip)的理解是,大部分压缩时间都是在进行一些浪费的猜测,以确定哪些内容可以压缩得很好,而解压器不需要面对这种成本,所以慢速只是压缩的问题。但答案可能因算法和其他细节(如硬件速度)而有所不同。例如,CPU 压缩/解压缩的速度有多快,较小的压缩数据对于其他硬件处理(压缩)数据的时间成本有多大帮助。 - TOOGAM
3个回答

65

这是一个非常好的问题,而且是一个鲜为人知的问题。你的直觉很正确——对于某些压缩算法来说,选择最高级别的压缩可能会导致解压缩时需要更多的处理。

幸运的是,gzip并不是这种情况——客户端/浏览器解压更加压缩的gzip文件(例如选择压缩级别9而不是6,假设大多数服务器使用的标准zlib代码库)并没有额外的开销。最好的衡量指标是解压缩速率,以MB /秒为单位,在同时监控内存和CPU等开销。仅按解压时间计算是不好的,因为在更高的压缩设置下文件更小,如果只使用秒表计时,我们无法控制该因素。

  1. 当压缩内容超过级别6时,gzip解压缩时间和内存使用都会迅速呈现渐近线性。在Marcus Müller提供的测试结果中,级别7、8和9的解压缩时间保持不变,但这是以整秒为粒度的粗略数据。

  2. 你还会注意到在这些结果中,所有压缩级别的解压缩内存需求都为0.1 MiB。这几乎是不可思议的,在软件领域里我们很少能看到这样的卓越表现。Mark Adler 和他的同事们为所取得的成就应该受到赞扬。gzip是一个非常好的格式。

内存使用涉及到你关于开销的问题。实际上,几乎没有任何开销。在浏览器解压缩速度方面,选择压缩级别9的收益并不多,但你不会失去任何东西。

现在,查看 这些测试结果 ,了解更多信息。您会发现,在压缩级别为9的内容中,gzip解压缩速率比较低的级别稍微 更快(例如,在级别6时,解压缩速率比在级别9时慢约0.9%)。这很有趣且令人惊讶。我不认为速率会提高。那只是一组测试结果 - 在其他情况下可能不适用(而且无论如何差异都相当小)。

最后说明:预压缩静态文件是个好主意,但我不建议使用gzip-9。相反,您可以使用zopfli或libdeflate获得比gzip-9更小的文件。Zopfli是Google的一个成熟的gzip压缩器。libdeflate是新的但非常出色。在我的测试中,它始终优于gzip-9,但仍落后于zopfli。您还可以使用7-Zip创建gzip文件,并且它将始终优于gzip-9。(在此前,gzip-9指的是Apache和nginx使用的规范gzip或zlib应用程序)。


你是否知道Brotli解压缩是否也不会受到更高压缩级别的负面影响? - jonsploder

22

不,当使用最大压缩级别时,在解压方面没有任何不利影响。事实上,有一个微小的好处,那就是更好地压缩的数据可以更快地解压缩。原因很简单,那就是解压器需要处理的压缩比特数更少。


9

实际上,在真实世界的测量中,更高的压缩级别会导致较低的解压时间(这可能主要是因为您需要处理更少的永久存储和更少的RAM访问)。

由于实际上,大多数在客户端使用数据的事情与解压缩相比都是相当昂贵的,您根本不需要关心这个问题。

此外,请注意,对于静态图像等静态资产,通常已经应用了哈夫曼/ zlib编码(PNG仅使用zlib!),您不必通过gzip获得太多收益。实际上,通常小图像(例如图标)适合单个TCP数据包(忽略HTTP头,有时比图像本身更大),因此您不会获得任何速度增益(但可以节省传输体积的费用-如果您提供 TB 的小图像。现在,我可以假设您并非Google本身... 此外,我想向您指出更高级别的优化,例如可以将您的JavaScript代码转换为更紧凑的形式的工具(例如,删除空格,将私有变量从my_mother_really_likes_this_number_of_unicorns重命名为m1);还有像JQuery这样的东西以“预压缩”形式存在。HTML也是如此。这并不会使调试变得更容易,但由于您似乎对最终节省空间感兴趣...


感谢您的回复和提供基准测试链接。我已经在我的Grunt构建中使用缩小所有静态资源 :) 没错,我不是Google +带宽成本也不是一个问题。但是,由于我无论如何都要压缩我的文本资产(HTML/CSS/JS),所以与构建的一部分相比,使用-9标志而不是-6并不需要更多的努力,除了增加几秒钟的构建时间。我主要担心的是这样做是否会给客户端解压缩内容带来额外负担。根据那些结果似乎并没有,事实上可能会更快。 - David
你实际上需要区分“无负担”和“更快”,因为任何操作系统都会在gzip解码线程调用无法立即回复数据的文件读取或网络接收调用时切换进程或线程,因此尽管较大的文件可能需要更长时间来解码,但这可能不是由于CPU时间,而是解码器等待数据的时间--这是实际运行客户端软件的计算机可以做其他事情的时间。但是就所有实际目的而言,这对客户端来说不应该有明显的恶化(除非您尝试将Chrome移植到计算器)。 - Marcus Müller
2
解压在相同的输入数据上使用更高的压缩级别会更快的原因非常简单,那就是解压器需要处理的输入数据更少。 - Mark Adler
@MarkAdler 噢,我才意识到你就是那个 Adler。你能阅读我的压缩答案,我感到十分荣幸! - Marcus Müller
@RonJohn 谢谢你提醒!已经用 archive.org 的快照替换了它。 - Marcus Müller

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