为什么有些压缩文件解压那么慢
前言
最近在折腾嵌入式环境和交叉编译时,有一次发现这个问题:
为什么有些压缩文件解压得这么慢?
尤其是在 Windows 上解压 GNU 源码的 .tar.xz 时,进度条几乎冻结。这种体验几乎人人都遇到过,但大多数时候我们只会骂一句“这包有病”,然后继续等。
那么,不同压缩格式,究竟在“换”什么?
总览
首先,压缩和解压缩的根本是:
压缩 = 用计算时间换空间
解压 = 用空间结构换计算
文件压缩的三种境界
先从zip文件入手:Level 1 LZ家族
代表格式:zip, gzip, zstd
它们的核心思想是:
“刚刚出现过的字符串,再出现就不写一遍了”
例如:
abcdefg ... abcdefg
第二次出现时:
(向后 123 字节,长度 7)
影响结果:
压缩率:中等
速度:很快
内存占用:低
这就是为什么:
-
.zip 解压快
-
体积一般
统计手段 Level 2:Huffman家族
代表格式:gzip, zstd, bz2
在 Level 1 基础上:
出现多的字符 → 用短编码
出现少的字符 → 用长编码
就像摩斯电码:
E → .
Q → --.-
代价:
要先扫一遍数据 -> 建统计表
这一步开始明显吃 CPU
我用数学压你 Level 3:LZMA / xz
代表:.xz
这里开始“变态”了。
它会做什么?
非常大的滑动窗口(几十 MB)
非常复杂的概率模型
非常深的回溯搜索
本质上在做:
“在尽可能大的历史范围内,
找到最优的重复表示方式”
结果就是:
压缩率:极高(Qt 源码这种文本天堂)
解压速度:慢
内存:吃得狠
为什么 .xz 解压这么慢?
这是很多人第一次解源码都会骂的点。
真实原因不是“算法慢”
而是:
解压过程本身就是在执行一个巨大的概率解码器
它在干三件事:
按 bit 读(不是字节)
↓
动态更新概率模型
↓
不停地做分支预测
这三件事对 CPU 来说都很不友好。
但是优点是可以做到对大量重复文本的极致压缩。
这在过去,对节省网络带宽和存储容量是神助,不知道节省世界多少钱和时间。
文件压缩的根本哲学
.xz 使用的是 LZMA 系列算法,它的风格可以概括为一句话:
我宁愿算到天荒地老,也要把你压到最小。
.zip 的哲学几乎是另一个极端:
够用就行,别太聪明。
不同压缩格式,其实是不同年代的选择
.tar.gz
老工程师的安全牌
稳定、快、压缩率尚可
.zip
普世通用格式
为兼容性而生
.tar.bz2
早期追求更高压缩率的尝试
现在逐渐被淘汰
.tar.xz
理论派、极致派
带宽比时间贵的时代产物
.tar.zst
现代工程折中方案
在速度和压缩率之间重新平衡
不同历史阶段的工程答案并存,在不同历史时刻,给出了不同历史答卷。压缩文件的繁荣也是社会的繁荣。
所以,慢不代表差。慢也是工程师的浪漫。
等待的时间,可以拿来干别的事情,比如喝杯咖啡、看看风景、给爱人发条消息,或者拿来写一篇博客。
也许科技发展了,带宽和存储不再是瓶颈,你的等待也变成了多此一举,但是别忘了,这个世界就是靠这些tar.xz建设起来的。至少在过去,它不是在浪费你的时间,而是在为另一个维度节省成本。
就当是体谅千千万万工程师好了,说不定你的等待,也是他们为了让你不要忘记他们的小心思。
留下评论