本文由公众号「LabHub」文章重写发布,原文含更多配图与细节。
问题背景:固件 OTA 的压缩困境
嵌入式设备做 OTA 升级时,固件包通常需要压缩传输。但在 MCU 上解压,有两个绕不开的矛盾:
- 解压速度——设备端内存和算力有限,解压慢一秒,用户体验就差一秒
- 压缩比——压缩比高的算法(如 Zstd)解压往往更慢,而解压快的(如 LZ4)压缩比又一般
传统方案总得在这两者之间二选一。直到我看到 zxc 这个 C 库——它想两个都要。
核心思路:不对称压缩
zxc 的定位很明确:把压缩的活全推给压缩方,解压方只做最少的活。
这个设计建立在"写一次、读很多次"的假设上:固件包在构建期压缩一次,在成千上万台设备上解压无数次。既然解压是高频操作,那就让解压路径尽可能轻——这是它和传统对称压缩库最大的区别。
项目信息:432 Star,BSD-3 协议,作者 Bertrand Lebonnois。
实测数据:解压确实快
官方 README 的 benchmark 数据(Apple Silicon M2 实测,已并入 lzbench 和 TurboBench 两个基准套件,可复现):
| 对比档位 | ZXC 解码速度 | LZ4 解码速度 | 差距 |
|---|---|---|---|
| -1 最高速 | 12699 MB/s | 5607 MB/s | 2.26x 快 |
| -3 标准 | 7020 MB/s | 4769 MB/s | 1.47x 快 |
| -6 高密度 | 6111 MB/s | 4521 MB/s | 1.35x 快 |
| -7 极限 | 4240 MB/s | 1803 MB/s | 2.35x 快 |

注意最后一列:每个档位的压缩比都不比 LZ4 差,有的还更小(-0.5% 到 -1.8%)。也就是说它不是拿体积换速度,是体积和速度双赢。在 ARM64 上优势最明显,x86 上也有 9% 到 48% 的提升。
12699 MB/s 是什么概念?一秒钟解压 12GB,相当于两分钟读完一张蓝光碟。把 8MB 固件包压到 5MB 再解压,设备端几乎感觉不到时间流逝。
快速上手
zxc 的发行渠道很全,Homebrew、Conan、vcpkg 都有:
# Homebrew
brew install zxc# 或从源码编译(CMake 构建)
git clone https://github.com/hellobertrand/zxc
cd zxc && mkdir build && cd build
cmake .. && make
踩坑提醒
- Seekable 要主动开:想要 O(1) 随机访问解压,压缩时必须加
-S参数,忘了就只能顺序解压 - 字典解压必须显式传:字典是外部
.zxd文件,文件头只存 32 位 dict_id 不自动查找,传错报 MISMATCH - 压缩慢是特性不是 bug:写一次读多次的设计,压缩 8MB 固件要几秒,解压几十毫秒。数据既写又读频繁的场景别用
适用场景
zxc 最合适的场景就是固件 OTA:构建期压缩一次,设备端解压无数次。如果你做嵌入式 OTA、镜像分发、或者任何"压缩一次、解压多次"的场景,值得一试。
如果你的场景是解压路径特别窄的 MCU,或者想要纯 C 无依赖的压缩库,zxc 值得放进选型清单对比。
我的公众号「LabHub」会先发这类文章(含更多步骤和配图),微信搜一搜直接搜「LabHub」就能找到。
关注后每周都有新折腾:拆设备、玩无线电、刷固件、变废为宝。