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 基金会资助本次工作
相关推荐
猫头虎-前端技术12 分钟前
HTML 与 CSS 的布局机制(盒模型、盒子定位、浮动、Flexbox、Grid)问题总结大全
前端·javascript·css·vue.js·react.js·前端框架·html
Skrrapper16 分钟前
【三大前端语言之一】静态网页语言:HTML详解
前端·html
网小鱼的学习笔记17 分钟前
html中的table标签以及相关标签
开发语言·前端·python·html
天蓝色的鱼鱼20 分钟前
Vue重复提交防御体系从入门到精通
前端·vue.js
海的诗篇_1 小时前
前端开发面试题总结-vue2框架篇(四)
前端·css·面试·vue·html
用户426670591691 小时前
为什么说不可信的Wi-Fi不要随便连接?
前端
玺同学2 小时前
从卡顿到流畅:前端渲染性能深度解析与实战指南
前端·javascript·性能优化
光影少年2 小时前
vuex中的辅助函数怎样使用
前端·javascript
teeeeeeemo2 小时前
JS数据类型检测方法总结
开发语言·前端·javascript·笔记
木木黄木木2 小时前
HTML5 火焰字体效果教程
前端·html·html5