用 Rust 重写
摘要
本文评估了2026年的‘Rewrite It In Rust’运动,讨论了现实世界中的性能提升、诸如新错误和平台支持等挑战,并提倡增量重写而非完全重写。
暂无内容
查看缓存全文
缓存时间: 2026/08/20 07:13
# 用Rust重写:性能、失败与2026年现实审视
来源:https://blog.jetbrains.com/rust/2026/08/10/rewriting-in-rust/
Rust标志 (https://blog.jetbrains.com/rust/)专注于重要之事
RustRover (https://blog.jetbrains.com/rust/category/rustrover/)
## 是极速还是过度炒作?用Rust重写的现实审视
*本文由**cot\.rs* (https://cot.rs/)*的共同维护者Mateusz Maćkowski和Marek Grzelak guest撰写,他们也是**Rustikon 2026* (https://www.rustikon.dev/)*的演讲者。您可以*观看完整演讲* (https://www.youtube.com/watch?v=eg_FXIAMA5g)\。
RIIR。如果你在开源社区待过一段时间,你一定见过它。有人在C或C++项目上提issue,建议为了内存安全和性能用Rust重写。有时这是个严肃的提议。有时这只是个梗。2026年,坦白说,它有点两者兼具。
我们想找出真相到底是什么。不是理论上,而是通过考察当人们真正去做时实际发生了什么。收益、性能数据、那些三年后被废弃的项目,以及在新鲜出炉的Rust代码中出现的CVE。我们身处这个生态系统已久,见识过这一切,而这篇基于我们Rustikon 2026演讲的博文,就是我们尝试对其进行一次诚实审视的努力。
**摘要**
- RIIR可以带来真正的性能和安全提升,但并非自动实现。有些项目因Rust而更快,有些只是因为它们被从头重写。
- 重写会引入新bug。即使资金充足、经验丰富的团队也会犯错。
- 并非每次重写都成功。Prisma、Loglog Games以及curl/hyper集成都因不同原因碰壁。
- 二进制大小、平台支持以及与其他语言的互操作性是实实在在的挑战。
- 最佳方法几乎总是增量扩展,而非一次性重写所有代码。
- Linux内核和Windows中的Rust,可以说是RIIR运动获得的最大认可。
## 什么是RIIR?为何它如此流行?
RIIR代表"Rewrite It In Rust"(用Rust重写)。这个短语开始出现在C和C++项目的issue追踪器中,作为迁移到一种内存安全、高性能替代方案的建议。根据Google Trends数据,"rewrite rust"一词大约在2022年开始显著攀升,我们认为这大致与Rust 2021版发布同期,尽管当时发生了太多事,我们不敢肯定。
人们在考虑重写时选择Rust,原因归结为三点:
1. **内存安全**
2. **性能**
3. **无畏并发**
在内存安全方面,Android团队的数据难以反驳。在Android开始将新开发转向内存安全语言后(https://security.googleblog.com/2024/09/eliminating-memory-safety-vulnerabilities-Android.html),代码库中Rust代码的速度稳步增长。数据显示出清晰的线性相关性:随着内存不安全代码速度的降低,内存安全漏洞的数量也随之减少(https://blog.google/security/rust-in-android-move-fast-fix-things/)。
就性能而言,一篇2017年比较编程语言能效、执行时间和内存使用的论文将Rust在能效和执行速度方面都排在前列(https://dl.acm.org/doi/epdf/10.1145/3136014.3136031)。该方法论并非完美,语言之间的直接比较也很困难,但结果仍指向一个更广泛的趋势:Rust在速度和效率上都表现不俗。内存使用量虽然高于绝对最佳者,但仍处于比较范围的上半区。
然后还有Stack Overflow开发者调查(https://survey.stackoverflow.co/2025/technology#admired-and-desired)。Rust已连续多年成为最受喜爱的语言。很多RIIR项目之所以存在,可能仅仅是因为开发者想用Rust。这一点值得坦诚承认。
## 三种重写类型
并非所有重写都相同,明确你所谈论的类别会很有帮助。这里我们有三类。
**直接替代品**旨在功能上与原版完全相同。你替换二进制文件,其他一切不变。像uutils coreutils (https://github.com/uutils/coreutils)、sudo-rs (https://github.com/trifectatechfoundation/sudo-rs)、作为容器运行时替代品的youki (https://github.com/containers/youki),以及作为Tor重新实现的Arti (https://gitlab.torproject.org/tpo/core/arti)都属于此类。生态系统中有成千上万这样的项目,从小的文件格式库(如用PNG crate替换libpng),到有严肃企业和社区资金支持的大型基础设施项目。
**替代方案**解决相同问题但做出不同选择。rigrep代替grep,delta代替diff,bat代替cat,Typst (https://typst.app/)代替LaTeX (https://www.latex-project.org/),Polars代替pandas (https://blog.jetbrains.com/pycharm/2024/07/polars-vs-pandas/)。它们并非试图成为完全相同的替代品。它们通常更快、更符合人体工程学,或基于不同的理念设计。Typst是可读性论点的一个好例子:
LaTeX和Typst可以产生相同的输出,但源代码讲述的故事截然不同。而在原始性能方面,Marek在一个37GB的cargo目标目录中搜索“cot”一词,同时运行了ripgrep和grep。grep耗时52秒。ripgrep耗时6秒。这不是微不足道的差异。
**自我重写**是指现有项目决定将其部分或全部用Rust重写,而不替换外部二进制文件。Firefox、Linux内核、Windows、Cloudflare的基础设施和Fish shell都属于此列。这些都不是小赌注。世界上一些部署最广泛的软件现在都包含了Rust,它们就是通过这种方式实现的。
## Rust重写的性能:它真的有效吗?
有时是的。有时是因为错误的原因。看uutils,sort运行速度几乎是GNU sort的四倍。原因是并行归并排序,Rust的并发模型使其实现起来相当容易且正确。但其他一些工具更快,仅仅因为它们是拥有30年后见之明的全新重写。原项目无法如此自由地试验,因为生产环境用户依赖它。
PNG crate是展示Rust特定优势的更好例子。Rust实现几乎比libpng快一倍。部分原因是自动向量化:Rust编译器可以从常规for循环自动生成SIMD指令,而大多数C实现需要手写SIMD。另一部分原因是流式DEFLATE解压缩,它一次将更多数据加载到CPU缓存中。两者都是真正的Rust优势。
## Rust二进制大小:问题及解决方案
Rust二进制文件以体积庞大著称,原因很真实:panic处理代码、Debug trait实现、编译到每个二进制文件的标准库、来自泛型的单态化,以及所有依赖项的静态链接。
uutils通过多调用二进制格式处理了这个问题,BusyBox也采用了相同的方法。所有工具都编译到一个二进制文件中,并通过符号链接调用。结果:原本73 MB的单个二进制文件变成了13.8 MB的多调用二进制文件,这实际上优于GNU coreutils标准安装的18.4 MB。使用UPX压缩后,可降至5 MB。
这个问题是可以解决的,但需要付出巨大努力。
## 用Rust重写:哪些可能出错?为何会出错?
这部分讨论得还不够。每次重写都会引入新bug。你是从头编写代码,这意味着你不可避免地会引入原项目中没有的新bug或回归问题。这不仅仅是Rust的问题;这是软件重写的问题。但值得对此保持清醒的认识。
Cloudflare在一个请求评分组件中引入了unwrap。uutils的日期格式稍有错误,破坏了无人值守升级。sudo-rs在超时后将部分输入的密码回显到终端。Linux内核中第一个Rust代码的CVE(https://lore.kernel.org/linux-cve-announce/2025121614-CVE-2025-68260-558d@gregkh/T/#u)来自Android binder驱动程序中unsafe块里的一个竞态条件。TARmageddon是async-tar中由错误解析.tar格式引起的RCE漏洞。
如果资金雄厚、经验丰富的团队仍会犯这些错误,我们也会犯。这不是不重写的理由,但确实是认真对待测试的理由。
有时,Rust甚至根本不是正确的选择。微软(https://www.microsoft.com/sr-latn-rs)选择Go(https://go.dev/)来重写TypeScript编译器,很大程度上是因为Go在编程模型上更接近TypeScript,这很重要,因为代码库在相当长一段时间内将包含两种语言。NTPsec项目(https://www.ntpsec.org/)选择Go是因为当时Go有更好的网络原语和更少碎片化的生态系统。这些是合理的决定,而非想象力的失败。
有些选择Rust的重写也没有成功。Prisma从Rust查询引擎(https://www.prisma.io/blog/prisma-orm-manifesto)迁移回TypeScript,原因是技能差距、部署复杂性和运行时问题。Loglog Games(https://loglog.games/)在进行了三年的游戏开发(https://loglog.games/blog/leaving-rust-gamedev/)后放弃了Rust。他们发现Rust非常适合重构,但迭代速度差,并指出Rust游戏开发社区更关注引擎技术细节而非完成最终游戏。curl/hyper集成达到了95%完成度(https://www.phoronix.com/news/Curl-Drops-Rust-Hyper-Backend),然后因最后5%的困难和缺乏社区动力而被放弃。有趣的是,这种合作仍然使两个项目都受益:尝试集成的过程迫使双方代码库进行了清理。
## 许可证是一个真实的决定
在RIIR讨论中没有被充分讨论的一点是,如果你正在创建一个重新实现现有项目的新项目,你的许可证选择会产生影响。
更严格的许可证,如GPL,可能会将无法在专有项目中引入copyleft依赖的用户排除在外。更宽松的许可证可能会招致开源社区的批评,因为一些人担心公司会使用代码而不回馈。没有普遍正确的答案。这完全取决于你的项目目标和社区。但这是一个值得有意识做出的决定,而非默认选择。
## 2026年,RIIR运动还在进行吗?
RIIR这个梗已经有些褪色。但实际运动并未停止。Linux内核(https://www.kernel.org/)中的Rust已不再是实验性的,维护者在2025年维护者峰会(https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/features-add-ons/maintainer-summit/)上宣布该实验成功。Rust正在Windows内核中运行。Cloudflare(https://www.cloudflare.com/)、Firefox(https://www.firefox.com/)以及无数基础设施项目已向生产环境提交了大量Rust代码。
规模是真实的。仅在Linux和Windows上,Rust就运行在数十亿台设备上。这可以说是"用Rust重写"这一想法有史以来获得的最大认可。
## 如何真正做好
如果你在考虑重写,我们建议先思考以下几点。确保它确实对你的用例有意义。问一下你的代码库是否使用了内存不安全语言,它是否是关键软件,你是否有真实的性能和可靠性需求,以及你是否有大量难以推理的并行或并发代码。你勾选的条件越多,理由就越充分。
确保你的团队已准备好。要么他们已经了解Rust,要么他们真心愿意学习并为之做出贡献。谷歌的数据表明,大约三分之二的开发者(https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html)能在两个月内有信心为Rust代码库做出贡献。但这并非保证,重写的最后5%几乎总是比你预期的更难。小规模重写需要数月。中等规模需要一到两年,大规模重写则需要两到五年。它几乎总是比你估计的要长。
更倾向于增量扩展而非完全重写。在保持旧代码库运行的同时,用Rust添加新组件,几乎总是比完全替换风险更小。你既能获得好处,又不必将整个项目押注于此。
当你确实要重写时,构建一个严肃的测试套件。实践中最好的例子是uutils,它运行在GNU coreutils官方测试套件上以跟踪对等性。截至2026年初,其通过率为92.2%,并且还在上升。
## 那么,它值得吗?
如果你的项目使用内存不安全语言编写,处理关键功能,有真实的性能需求,并且涉及大量并发代码,是的。重写是强有力的、有证据支持的选择。
超出这些条件,它仍然可能值得,但分析需要更加谨慎。热情可以理解,因为Rust确实很优秀。但它被设计为系统编程语言,这正是它发挥最佳作用的地方。将RIIR视为每个性能或安全问题的默认答案,就是你最终得到一个为期两年的重写项目,推迟六个月交付,并引入你已修复过的bug的原因。
### 常见问题解答
**RIIR是什么意思?** RIIR代表"Rewrite It In Rust"(用Rust重写)。它始于开源issue追踪器中为了内存安全和性能将C和C++项目迁移到Rust的建议,并成为Rust社区中更广泛的文化梗。
**用Rust重写软件值得吗?** 这取决于你的情况。如果你的代码库使用内存不安全语言编写,处理关键功能,并且有真实的性能或并发需求,用Rust重写的理由就很充分。在其他情况下,好处不那么明显,而成本——学习曲线、重写时间和新bug——则值得认真考虑。
**用Rust重写有哪些风险?** 每次重写都会引入新bug,包括原项目已修复的bug。Rust重写还需要开发者学习这门语言,可能花费远超预期的时间,并可能面临平台支持、二进制大小以及与其他语言互操作性的挑战。
**迁移到Rust的最佳方法是什么?** 增量扩展而非完全重写。在保持现有代码运行的同时,用Rust添加新组件。当你确实要重写时,投入资源构建一个全面的测试套件,以验证新实现的行为与原版完全一致。
**Rust在Linux内核中成功了吗?** 是的。在2025年Linux内核维护者峰会上,共识是Rust实验是成功的。Rust现在是内核的核心部分,不再被视为实验性。
#### 订阅Rust博客更新
https://blog.jetbrains.com/rust/2026/08/10/rewriting-in-rust/#
## 发现更多
相似文章
如何将C/C++项目重写为Rust?
本文讨论了将C/C++项目迁移到Rust的策略,强调增量迁移而非全面重写,并引用了Luca Palmieri和JetBrains的见解。
Bun的Rust重写进展如何?
对Bun使用Anthropic的AI进行Rust重写的深入分析,质疑其成本、效果及持续的维护挑战,包括数千个未解决的PR以及声称完成后数月仍未发布新版本。
Bun 的 Rust 重写已合并
Bun JavaScript 运行时和工具包已用 Rust 重写,标志着从原本的 Zig 实现发生了重大转变。
我们如何(及为何)将生产环境的C++前端基础设施重写为Rust
NearlyFreeSpeech.NET 将其生产环境的C++前端基础设施(nfsncore)重写为Rust,该系统负责所有传入请求的路由、缓存和访问控制。迁移的动机是Rust的安全性保证、性能、生态系统优势以及老化的C++代码库的局限性。
如何在2026年9月加速Rust编译器
该文章报告了Rust编译器在两个月内平均编译时间减少了4.57%,重点介绍了rustdoc、Clippy的优化、LLVM升级,以及新的Polonius借用检查器和Penelope Hammertime特征求解器。