bzip2 crate 从 C 切换为 100% Rust 实现

本文来自 trifectatech.org/blog/bzip2-...

今天我们发布了 bzip2 版本 0.6.0,它默认使用我们用 Rust 实现的 bzip2 算法库 ------ libbz2-rs-sys。这意味着 bzip2 crate 现在更快、更容易进行交叉编译。

如果你有 C 项目,也可以将 libbz2-rs-sys 构建为 C 动态库,以便受益于这些改进。

为什么要做这件事?

为什么要为一个 90 年代的算法费心投入?虽然 bzip2 现在用途不广,但很多协议和库仍需支持它,以符合规范要求。因此很多项目的依赖树深处仍然依赖 bzip2。

我们借助从 zlib-rs 积累的经验,对 bzip2 实现进行了现代化重构。

我们曾在《使用 c2rust 翻译 bzip2》中写过 libbz2-rs-sys 的实现细节。现在让我们看看这些工作的实际收益。

性能提升

我们的 Rust 实现通常比 C 实现更快。虽然在某些场景下只是持平,但我们尚未遇到明显更慢的情况。

在压缩方面,我们快了不少。对于 bzip2 来说,level 表示使用的工作内存量,对性能影响不大。在 sample3.ref 上,level 1 就已经分配了比文件还大的内存,因此更高等级几乎无意义。

文件名 C(CPU 周期) Rust(CPU 周期) 性能提升
sample3.ref(level 1) 38.51M ± 77.03K 33.53M ± 90.52K -14.87%
silesia-small.tar(level 1) 3.43G ± 2.06M 3.00G ± 6.31M -14.30%
silesia-small.tar(level 9) 3.47G ± 4.86M 3.17G ± 4.43M -9.66%

在解压缩方面,虽然差异更分散,但总体上依然有显著提速:

文件名 C(CPU 周期) Rust(CPU 周期) 性能提升
sample3.bz2 2.53M ± 30.08K 2.42M ± 8.95K -4.48%
sample1.bz2 9.63M ± 40.44K 8.86M ± 10.64K -8.63%
sample2.bz2 20.47M ± 55.28K 19.02M ± 36.13K -7.67%
dancing-color.ps.bz2 87.46M ± 481.02K 83.16M ± 548.86K -5.17%
re2-exhaustive.txt.bz2 1.89G ± 12.29M 1.76G ± 12.64M -7.65%
zip64support.tar.bz2 2.32G ± 12.09M 2.11G ± 15.42M -10.00%

注意事项 :在我们的 macOS 基准机上,解压性能偶尔会出现较低的数值。我们尚未找到具体原因;在 macOS 上进行细致性能分析相当困难(例如找不到像 perf 这样的性能追踪工具可用)。

实现良好的交叉编译体验

Rust 项目如果依赖 C 通常也能进行交叉编译(依赖 cc crate),但一旦失败,错误会很难调试。系统库链接也常常引发混乱和难以复现的问题。

而 bzip2 在编译为 WebAssembly 时一直是个麻烦。通过去除 C 依赖、使用 Rust 实现,这类问题就自然消失了:交叉编译"直接就能用"。构建 Windows 或 Android 版本也变得简单。

这不仅提升了用户体验,也极大降低了维护负担。

默认不导出符号

C 依赖的符号会被导出,以便 Rust 的 extern 块能够调用。但如果另一个依赖也声明了相同符号,可能会发生冲突。

libbz2-rs-sys 默认不导出符号,这样就不会与其他库冲突。如果你的 Rust 项目确实需要导出符号,可以通过特性开关(feature flag)启用导出。

使用 MIRI 运行测试

要写出高性能的 bzip2 实现不可避免要用一些 unsafe 代码,复刻 C 接口的部分更是如此。幸运的是,我们能在 MIRI 下运行这些代码。

更重要的是,任何依赖 bzip2 的高层库或应用程序,现在也能在 MIRI 下进行验证。

安全审计

安全审计发现了一个逻辑错误(off-by-one 错误),并修复了一些 fuzzer 的限制。除此之外没有发现重大问题(太棒了!)。

特别感谢来自 Radically Open Security 的 Christian Reitter,他分享了 fuzzing 方面的专业经验。完整审计报告可以在项目页面查看。

结语

现在,bzip2 crate 更快了。你可以继续安心地"忘了它的存在"。

致谢

  • 感谢 Alex Crichton 共同维护 bzip2 crate
  • 感谢 Radically Open Security 的审计和专业建议
  • 感谢 NLnet 基金会资助本次工作
相关推荐
Csvn10 小时前
WASM
前端
修己xj11 小时前
我用 AI 给自己写了一个 Markdown 编辑器,然后把它开源了
前端
FRing0312 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
幸运小猿12 小时前
模拟慢上传-处理超时重试image 丢失线上问题
前端·javascript·html
moshuying13 小时前
网购能买Token了!
前端
h_654321014 小时前
echarts实现柱状图加一条横线
前端·echarts
风骏时光牛马14 小时前
生成一个后端标题,只需要一个标题,不需要其他的任何文本。
前端
子非鱼@Itfuture14 小时前
关于前后端联调中登录状态/登录信息失效?
java·前端
郭小李14 小时前
openFeign入门
java·开发语言·前端
馒头不想说话14 小时前
AI当运营,帮你省人力
前端