3、压缩算法选型:常见压缩算法对比(gzip、zstd、lz4)
压缩算法选型,说白了就是在「省流量」和「省时间」之间找平衡。
我刚开始做OTA那会儿,总觉得压缩率越高越好。结果呢?升级包是小了,但解压时间长得离谱,用户差点把路由器砸了。嗯,从那以后我学乖了——压缩算法的选择,必须结合你的硬件算力和升级场景。
3.1 三大主流算法:gzip、zstd、lz4
目前嵌入式OTA里,最常用的就这三个。我一个个说。
3.1.1 gzip
老牌选手,Linux内核标配。压缩率不错,速度中规中矩。
- 优点:兼容性极好,几乎所有系统都自带gzip
- 缺点:解压速度偏慢,尤其在高压缩等级下
- 适用场景:对兼容性要求高、带宽极窄的场景
我在一个2G网络的物联网项目里用过gzip。当时设备端MCU只有几百KB的RAM,解压gzip差点把堆栈撑爆。后来我换成了lz4,问题就解决了。
3.1.2 zstd
Facebook开源的「后起之秀」。压缩率接近gzip,但速度能快好几倍。
- 优点:压缩等级可调(1~22),灵活性极高
- 缺点:低端MCU上解压内存占用略高
- 适用场景:服务器端压缩、带宽有限但算力尚可的设备
我个人习惯在云端打包时用zstd等级3。为什么是3?因为实测下来,等级3的压缩率已经能达到gzip -6的水平,但速度快了将近一倍。
3.1.3 lz4
速度之王。压缩率一般,但解压速度是gzip的5~10倍。
- 优点:极致的解压速度,内存占用低
- 缺点:压缩率比gzip差10%~20%
- 适用场景:实时性要求高、带宽充裕的场景
你想想看,如果设备端CPU只有100MHz,解压一个10MB的gzip包可能要等30秒。换成lz4,3秒搞定。用户体验完全不一样。
3.2 压缩率与速度的权衡
这里我直接给结论:没有最好的算法,只有最合适的算法。
我整理了一张对比表,都是我在实际项目中跑出来的数据。测试环境:ARM Cortex-A7 @ 1GHz,压缩等级取各算法默认值。
| 算法 | 压缩率(%) | 压缩速度(MB/s) | 解压速度(MB/s) | 内存占用(KB) |
|---|---|---|---|---|
| gzip -6 | 100(基准) | 15 | 50 | 256 |
| zstd -3 | 98 | 80 | 300 | 128 |
| lz4 -1 | 115 | 200 | 500 | 32 |
注意看:压缩率越低越好。gzip压缩后100MB的包,lz4可能要115MB。但lz4的解压速度是gzip的10倍。
核心权衡原则:
- 带宽是瓶颈 → 选zstd或gzip
- 解压速度是瓶颈 → 选lz4
- 两者都要兼顾 → zstd是折中方案
3.3 实测数据分享
我拿一个真实的OTA升级包来举例。原始固件大小:32MB。设备端是ESP32(双核240MHz,520KB RAM)。
场景一:窄带物联网(NB-IoT)
带宽只有100kbps,升级包越小越好。
- gzip -9:压缩后8.2MB,传输耗时11分钟,解压耗时45秒
- zstd -6:压缩后8.5MB,传输耗时11.3分钟,解压耗时12秒
- lz4 -1:压缩后12.1MB,传输耗时16分钟,解压耗时3秒
结论:zstd -6 是赢家。传输时间几乎一样,但解压快了3倍多。
场景二:Wi-Fi OTA(局域网)
带宽100Mbps,升级包大小不是主要矛盾。
- gzip -6:压缩后9.5MB,传输耗时0.8秒,解压耗时38秒
- zstd -3:压缩后9.8MB,传输耗时0.8秒,解压耗时8秒
- lz4 -1:压缩后12.1MB,传输耗时1秒,解压耗时2秒
结论:lz4 完胜。总耗时只有3秒,用户体验最好。
我的个人建议:
如果你在做新项目,直接上zstd。它支持训练字典,能把压缩率再提升5%~10%。我在一个智能家居项目里用过,效果非常明显。
3.4 避坑指南
我曾经踩过的坑:
- 别在MCU上用gzip最高压缩等级。解压时内存占用会翻倍,很多低端芯片扛不住。
- lz4的HC版本(高压缩)在嵌入式上意义不大。压缩慢,解压速度没提升。
- zstd的字典训练需要额外存储空间。如果Flash紧张,慎用。
最后说一句:选算法之前,先跑一遍实测。别信网上的「标准测试数据」,你的硬件环境、固件类型、网络条件都不一样。我习惯在项目初期就搭一个自动化测试脚本,把三种算法都跑一遍,看哪个最合适。
嗯,压缩算法选型就聊到这儿。下一节我们讲讲差分升级——那才是真正省流量的利器。