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紧张,慎用。

最后说一句:选算法之前,先跑一遍实测。别信网上的「标准测试数据」,你的硬件环境、固件类型、网络条件都不一样。我习惯在项目初期就搭一个自动化测试脚本,把三种算法都跑一遍,看哪个最合适。

嗯,压缩算法选型就聊到这儿。下一节我们讲讲差分升级——那才是真正省流量的利器。