知其然,知其所以然
数据编码与压缩 2026-10-12

zstd 的熵编码:FSE/ANS 为什么比 Huffman 更接近熵

自己写 rANS 和 tANS(FSE 风格)并往返验证:偏斜分布 0.9/0.1 下 Huffman 比熵多 112.7%、rANS 只多 0.02%;表大小 2^10–2^12 就贴着熵;但对 LZ77 的 token 流,换成 ANS 只比 Huffman 小 0.2%,zstd-19 比 zlib-9 小 11.6% 的主要原因在别处。

压缩原理 ANS FSE rANS tANS Huffman zstd 熵编码 Python 真实验证 动画演示
数据编码与压缩 2026-10-12

zstd 的压缩级别:用更多时间换更小的体积到底怎么换

实测 zstd 级别 -5 到 22:从级别 3 到 19 体积小 21% 但压缩慢 130 倍;解压速度与级别无关(约 1700–2000 MiB/s);级别 22 需要 128.7 MiB 压缩内存;和 gzip、lz4、snappy、xz、brotli 的压缩比—速度对照;多线程只在较低级别加速。

压缩原理 zstd 压缩级别 压缩速度 解压速度 内存 多线程 lz4 xz brotli Python 真实验证 动画演示
数据编码与压缩 2026-10-12

Snappy 与 LZ4:不做熵编码换来的速度

自己写解析器拆开 LZ4 block 和 Snappy 的真实输出:没有熵编码,字面量原样存放,偏移最大 65535;products 上 LZ4 的 338418 字节里元数据占 58%;速度优先的压缩器压缩比比 zstd-3 低 40% 以上;短输入的固定开销。

压缩原理 Snappy LZ4 block 格式 熵编码 偏移 Python 真实验证 动画演示
数据编码与压缩 2026-10-12

窗口与内存:往回看得越远压缩得越小,代价是什么

窗口决定压缩器能往回看多远:重复相隔 1 MiB 要 windowLog 21 才找得到;windowLog 27 也找不到相隔 16 MiB 的重复,要开长距离匹配;压缩端声明了大窗口,解压端不准备足够内存就会失败;每个 4 KiB 对象单独压缩比整体压缩大 62%。

压缩原理 窗口 windowLog 长距离匹配 zstd 解压内存 gzip 分块 Python 真实验证 动画演示
数据编码与压缩 2026-10-12

zstd 字典:几百字节的小记录为什么能压到原来的零头

实测 zstd 字典:单条 360 字节的商品记录无字典只有 1.25×、16 KiB 字典 3.30×;54 字节的行无字典反而变大(0.86×);1 KiB 字典就能从 288.6 降到约 130 字节/条;数据漂移后旧字典变差,重新训练恢复;解压端没有同一份字典会失败。

压缩原理 zstd 字典 小对象 字典训练 ZstdCompressionDict Python 真实验证 动画演示
数据编码与压缩 2026-10-12

gzip 与 brotli:HTTP 上的压缩,brotli 的内置字典

在 HTTP 场景里比较 gzip、brotli、zstd:brotli q5 在英文 HTML 样板上比 gzip 小 27%(应来自内置字典)、在乱码词上与 gzip 相同;requests 装了 brotli 和 zstandard 后会发 gzip, deflate, br, zstd;随机数据再压变大;brotli q11 现压缩每页 11 ms;慢网络压缩划算、快网络现压缩高级别不划算。

压缩原理 brotli gzip zstd HTTP Content-Encoding Accept-Encoding 静态字典 Python 真实验证 动画演示
数据编码与压缩 2026-10-12

编码加压缩的组合矩阵:体积与端到端耗时

3 种编码 × 7 种压缩的矩阵:products 上最小的是 JSON + brotli q11(是未压缩 JSON 的 14.1%);zstd-3 压缩后 Protobuf 比 JSON 大 3.5%;timeseries 上 JSON + zstd-19 比 Protobuf + zstd-19 小;压缩级别越高,编码格式之间的差距越小甚至反转;解码速度 Protobuf 快 3–5 倍。

编码 压缩 组合矩阵 JSON MessagePack Protobuf snappy lz4 zstd brotli 真实验证 动画演示
数据编码与压缩 2026-10-12

压缩过的 JSON 与 Protobuf:谁更小,什么时候该换格式

压缩过的 JSON 与 Protobuf:12 列里 JSON 压缩后有 8 列更小;把价格存整数分、分类存编号、去掉可推出的字段这类数据模型优化,收益(JSON 少 12.2%,Protobuf 少 25.1%)比换格式大;最小的是改了数据模型再按列排的 JSON(703321 字节,zstd-19)。

编码 压缩 Protobuf JSON 数据模型 列式 zstd Python 真实验证 动画演示
数据编码与压缩 2026-10-12

场景一:爬虫结果落盘,JSON Lines 加 zstd 对比 sqlite BLOB

爬虫结果落盘的 8 种方式:每条单独 zstd 的 sqlite BLOB 只省 12%,加 16 KiB 字典 34%,每 100 条一块 24.6%,整个文件一个 zstd 帧 18.5%;整个帧点查 7657.5 微秒对 5.5 微秒;关系列聚合 1.1 ms 对逐行 json.loads 58.5 ms;1500 个小文件按块多占 17.8%;sqlite 删了一半数据文件不缩小。

编码 压缩 存储 sqlite JSON Lines zstd BLOB 字典 VACUUM Python 真实验证 动画演示
数据编码与压缩 2026-10-12

场景二:Redis 里的任务体与页面缓存,小对象怎么压

在独立的 redis-server 上测队列里的任务体:10 万个 376 字节的任务,JSON 每任务占 392.9 字节、Protobuf 265.8、JSON + zstd 字典 52.8;入队出队吞吐不降;50 个任务打包成一个元素每任务只占 36.1 字节;页面缓存用 zstd 字典从 68.7 MiB 降到 14.9 MiB。

编码 压缩 Redis 任务队列 小对象 zstd 字典 内存 缓存 Python 真实验证 动画演示
数据编码与压缩 2026-10-12

选型总结:一张决策表和每条结论的前提

六个场景的选型,每个都附测得的数字和前提:单条小消息(Protobuf + 字典 106.5 字节,JSON + 字典 109.1)、批量归档(xz-9 988040 最小)、批量热数据(Protobuf + lz4 读 8.2 ms)、HTTP 动态响应(zstd-3 体积乘耗时最小)、缓存(zstd + 字典省 79%)、不值得压缩的情况。

编码 压缩 选型 决策表 JSON Protobuf zstd brotli lz4 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号