bijou64:比 LEB128 快几倍的可变长度整数编码,你会用吗?
2026/5/30 15:40:57 网站建设 项目流程

Tenfold:庆祝 Ink & Switch 成立 10 周年

2026 年 4 月,作者 Brooklyn Zelenka 分享了 [bijou64](https://github.com/inkandswitch/bijou/tree/main/bijou64) 这种小型编码的故事。bijou64 是一种可变长度整数(varint)编码,是为 [Subduction](https://github.com/inkandswitch/subduction) CRDT 同步协议开发的。它原本是为修复签名验证漏洞,让每个数字只有一种表示方式,结果运行速度比更常见的 varint [LEB128](https://en.wikipedia.org/wiki/LEB128) 快几倍。“bijou” 在法语中是 “小宝石” 的意思,还挺巧的。

问题所在

许多二进制协议需要紧凑编码整数,可变长度整数编码(“varints”)解决了这个问题,但多数设计没把规范性当回事,靠解码器运行时检查来强制规范。就拿最常见的 LEB128 来说,它把数字编码为一系列 7 位段,每个字节最高位表示 “还有更多字节”。不过,数字 `0` 在 LEB128 中有多种表示方式,这会给签名数据带来问题。要是每个数字只有一种唯一表示方式,存储时就能对数字序列去重。

规范化

一种解决办法是强制采用 “规范” 形式,编码时确保用规范编码,解码时验证是否符合格式。但有人会问:谁会故意用有问题的 varints 呢?答案是那些能从协议将不同字节串误认为相同值中获益的人。典型例子有 ASN.1 等,规范化攻击曾出现在多个协议中。bijou64 设计就是为避免这种问题,它不靠增加检查,而是让格式本身在不做规范化检查时,每个值只有一种规范编码。

(几乎)天生规范

bijou64 消除了每个整数多种编码的可能,就像日常数字系统,每个数字只有一种写法。它用了两个技巧:

首字节的双重作用:“首字节有时作为标签” 技术从 [VARU64](https://github.com/AljoschaMeyer/varu64-rs) 学来。首字节正常表示 0 - 247,248 - 255 是 “标签”,表示首字节后还需多少字节表示数字。这对解码有利,读取首字节就知道分配多少内存,而 LEB128 得不断读字节。

偏移量:仅靠标签不够,还把下一个字节偏移 248。比如 `0xF8 0x00 == 0xF8 == 248`,而不是 `0`。每个长度的数字都有可预测的偏移量,不过 9 字节的最大数值需手动检查范围。

基准测试

在 ARM(Apple M2 Pro)和 x86(AMD Zen 5)上的基准测试结果出乎意料。

解码:bijou64 解码速度相当快,即使不算 LEB128 规范检查开销,也比 LEB128 快 2 - 10 倍。小数字解码快约两倍,大数字快 8 - 10 倍。在均匀的全 `u64` 分布下,bijou64 处理一批 4096 个值约需 3 微秒,LEB128 约需 30 微秒。累积分布函数更能体现差异,bijou64 的 CDF 几乎垂直,LEB128 曲线向右倾斜延伸。规范解码时差距更大,bijou64 规范解码就是普通解码,其他编码则需额外工作。

编码:编码速度通常更快,但在 “小” 分布(248 - 65,535)下,LEB128 编码速度快约 1.24 倍。

编码大小:bijou64 不是所有分布下最紧凑的 varint 编码,实际工作负载中,它和 LEB128 的字节数相差在几个百分点以内。

原因分析

从首字节确定长度:bijou64 解码器和编码器能立即知道读写字节数,LEB128 解码器得扫描每个字节最高位。分支预测器喜欢 bijou64 的模式。

大端、连续的有效负载:bijou64 有效负载是连续大端整数,现代 CPU 有专门指令处理,LEB128 每个字节 7 位布局迫使解码器掩码和移位操作。

可预测的分支:层级选择是小的固定匹配,分支预测能快速稳定,这从陡峭的 CDF 曲线能看出来。

算术运算成本低:添加 `OFFSET[tier]` 是常量加载和 `add` 操作,算术版本指令更少。

你应该使用 bijou64 吗?

这取决于目标。bijou64 是新格式,没 LEB128 测试得多,LEB128 在主流语言中有成熟实现。基准测试结果鼓舞人,但论断需大量证据,目前只在三种 CPU 上测试过。LEB128 不会被淘汰,但如果设计新格式且规范性重要,bijou64 是更安全、运行更快的替代方案。

该库已发布,采用 MIT / Apache - 2.0 双许可证,规范遵循 [CC BY - SA 4.0](https://github.com/inkandswitch/bijou/blob/main/bijou64/SPEC.md),还有 Wasm/JavaScript 包装器,规划了宽度扩展。发现 bug 或性能问题可反馈。

研究领域

- 本地优先软件

- 可塑软件

- 可编程墨水

- 通用版本控制

联系我们

- 发邮件至 hello@inkandswitch.com

- 订阅 RSS 订阅源

- 在 Bluesky 上关注

- 在 Github 上查看代码

Ink & Switch 通讯

订阅时事通讯,了解实验室最新情况,可浏览存档。邮箱:[请输入邮箱地址]

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询