C++重写pigz成可嵌入库,可移植路径吞吐达pigz的2.1倍

pigzpp: Fast, Parallel, Portable Compression for the Whole Stack

Thamme Gowda

cs.DC

2026-08-25

从零用C++23把pigz收成无全局状态的库,挂zlib-ng和ISA-L两套核,接到五种语言。128MB文本level 6上,可移植路径是pigz的2.1倍,x86 ISA-L达8.5倍,体积大约多9%。

这篇在解决什么

gzip 仍是默认压缩:.gz、ZIP 里的 DEFLATE、PNG 的 IDAT、HTTP Content-Encoding、Docker/OCI 镜像层,下游几乎都认这一套。格式是单核时代设计的。Mark Adler 的 pigz 用分块并行把多核喂饱,命令行用了十几年。

卡住的是形态。pigz 把大约六十个可变字段塞进进程全局 struct g,作者在 Stack Overflow 上写过:「pigz is not a library。」今天调用更常来自 Python 数据管线、Go 服务、浏览器 WASM,没法直接嵌。各语言再各自包一层并行 gzip(Go 的 pgzip、Rust 的 gzp),同一份加速要写五遍。

方法

Thamme Gowda(微软,个人项目)用 C++23 从零重写,做成无全局状态、可重入的库。配置显式传入,线程用 C++20 std::jthread,热路径没有全局锁。

并行策略沿用 pigz:默认 128 KiB 分块丢进线程池。每个 worker 拿上一块末尾 32 KiB 当字典,跨块回指才能保住压缩率。CRC-32 也分块算,再用 crc32combine 在对数时间里折成文件级校验,不必重扫原文。一个写线程按输入顺序拼 gzip 头、块和 trailer。下游 gzip/pigz 能直接解。

内核挂两套静态链接的 DEFLATE 引擎:

同一套核接到 C++、Python(nanobind,一份 abi3 wheel 覆盖 CPython 3.12+)、WASM(Emscripten,含 SIMD 与 SharedArrayBuffer 多线程)、Go(cgo)、Rust(FFI)。ZIP 和 PNG 是应用层:ZIP 按成员走并行 DEFLATE,PNG 自己做 scanline filtering 再压进 IDAT。

相当一部分代码由 coding agent 在人指导下写。验收靠无损往返、与 gzip/unzip 交叉解码、测试套件和可重复基准。作者的判断是:有机械可检查的 oracle,agent 改得快也改得安全;真正难的是拆掉全局状态。

结果

测试机是 Ubuntu 22.04 WSL2,宿主机 Intel Xeon W-2235,虚拟机露出 5 核 10 逻辑处理器。主测 128 MB 中英维基文本、level 6、8 worker;一次热身加七次计时取中位数。

CLI(论文 Figure 1):

方法吞吐相对 pigz压缩比
gzip17 MB/s0.13×2.83
pigz133 MB/s2.83
pigzpp zlib-ng285 MB/s2.1×与 pigz 同
pigzpp ISA-L1124 MB/s8.5×大约多 9% 体积

语言绑定,同一份语料:

OCI 层用 python:3.12 最大一层 637 MB。stdlib gzip 压 19.6 秒;zlib-ng 381 MB/s(ratio 2.83),和 pgzip 的 376 MB/s(2.76)接近,大约 11× stdlib;ISA-L 约 42×,压到 0.5 秒。这是压缩阶段,不是端到端 docker build。

PNG 用 Kodak 24 张 768×512 RGB:fast 预设走 ISA-L,大约 Pillow 默认的 11.8×、OpenCV 的 1.6×,体积相当。ZIP 写入:同压缩率下 zlib 路径约 12× Python zipfile,ISA-L 最高 28×。解压:原生 711 MB/s,对照 pigz 212、gzip 166。

ISA-L 在 8 worker 见顶 1158 MB/s。WASM 无 ISA-L,8 worker 到 242 MB/s。

为什么重要

还在用 gzip 的流水线可以直接换。Zstd、Brotli、LZ4 在速度/压缩率前沿往往更好,但装机量在 gzip/ZIP/PNG/HTTP/OCI 上。pigzpp 的目标是把已经在用的格式喂饱现代 CPU,不推新格式。

对 Python 数据管线和容器构建最直接:不出进程就能拿到接近 CLI 的并行 gzip。ZIP/PNG 只是同一核上的便利层,别当成新编解码器。发布物静态链进 zlib-ng/ISA-L,CI 会拒带动态依赖的产物。

性能主要来自 vendored 的 zlib-ng 和 ISA-L,不是从零发明 DEFLATE。工程贡献是把 pigz 的并行设计收成可嵌入的一份核,五端一起吃到加速。AI 辅助重写能交差,前提是往返测试和交叉解码够硬。

局限与存疑

数字来自一台 x86-64 WSL2,没有原生 ARM64 吞吐。主测一份 128 MB 文本、一个 level,源码、二进制、不可压数据会走样。语言对比用的是各生态习惯 API,没把绑定开销拆开。CPU 亲和、睿频、调频都没锁。作者自己写了:「最快」只在这组实现、这台机器、这份语料里成立。

ISA-L 的 8.5× 是拿体积换的。PNG 的 11.8× 对照 Pillow 默认,不是所有调过参的 PNG 编码器。Docker 数字是单层压缩,构建里还有别的阶段。

AI 辅助过程写在两篇随笔里,论文几乎没有消融:哪些模块是人写的、测试漏了什么、和 pigz 有没有行为差异,正文核不出来。

术语

原文与代码

社区讨论

相关论文

全部论文解读