快得惊人,还是被吹得惊人?用 Rust 重写的现实检验

RIIR 是 “Rewrite It In Rust”(用 Rust 重写)的缩写。它最初常见于 C/C++ 开源项目的 issue:面对内存安全、性能或并发难题,总会有人提出“干脆用 Rust 重写”。这句话后来既成了技术迁移的认真建议,也成了 Rust 社区的一则经典玩笑。2022 年前后,随着 Rust 的影响力继续扩大,相关讨论明显增多。

本文为译文,译自 JetBrains Rust Blog 的 Blazingly Fast or Blazingly Hyped? A Reality Check on Rewriting in Rust。原文作者 Irina Mihajlovic,文章基于 Mateusz Maćkowski 和 Marek Grzelak 在 Rustikon 2026 的分享。


Irina Mihajlovic|2026 年 8 月 10 日

本文由 cot.rs 的共同维护者、Rustikon 2026 演讲者 Mateusz Maćkowski 和 Marek Grzelak 客座撰写。你可以在这里观看完整演讲

RIIR。如果你在开源社区待过一段时间,大概见过它。有人在某个 C 或 C++ 项目的 issue 里提出,为了内存安全和性能,不如用 Rust 重写。有时这是严肃提议,有时只是个梗。到了 2026 年,老实说,它两者都是。

我们想弄清楚,它究竟是哪一个。不是停留在理论上,而是看看人们实际这么做之后发生了什么:成功、性能数据、做了三年后被放弃的项目,以及刚写出来的 Rust 代码里出现的 CVE。我们在这个生态里待得够久,这些事都见过。本文基于我们在 Rustikon 2026 的演讲,是我们试着诚实看待这个问题的一次尝试。

TL;DR

  • RIIR 可以带来真实的性能和安全收益,但不会自动发生。有些项目因为 Rust 更快,有些只是因为从头重写了。
  • 重写会引入新的 bug。即使资金充足、工程师经验丰富的团队也会犯错。
  • 并非每次重写都会成功。Prisma、Loglog Games 和 curl/hyper 集成都因不同原因撞了墙。
  • 二进制体积、平台支持以及与其他语言的互操作性,都是实际存在的挑战。
  • 几乎总是应该选择渐进式扩展,而不是一次性重写全部。
  • Linux 内核和 Windows 中的 Rust,或许是 RIIR 运动迄今最有力的验证。

什么是 RIIR?它为什么流行起来?

RIIR 是 Rewrite It In Rust(用 Rust 重写)的缩写。这个说法最初出现在 C 和 C++ 项目的 issue tracker 中,用来建议迁移到一种内存安全、性能良好的替代语言。根据 Google Trends,“rewrite rust”一词从 2022 年左右开始明显上升。我们认为这大致与 Rust 2021 edition 的发布相吻合,不过那段时间发生了许多事,我们并不敢说自己能确定原因。

人们在考虑重写时会想到 Rust,主要有三个原因:

  • 内存安全
  • 性能
  • 无畏并发

谈到内存安全,Android 团队的数据很难反驳。Android 开始把新开发迁移到内存安全语言之后,代码库中 Rust 代码的增速稳步提高。数据呈现出清晰的线性相关:内存不安全代码的增速下降,内存安全漏洞的数量也随之下降。

Android 中内存不安全代码与内存安全漏洞的关系

性能方面,2017 年一篇比较不同编程语言能耗、执行时间和内存使用量的论文,将 Rust 在能效和执行速度两项上都排在前列。方法论并不完美,语言之间也难以直接比较;但结果仍指向一个更广泛的趋势:Rust 在速度和效率两方面都很有竞争力。它的内存使用量高于表现最好的语言,但仍处在比较结果的上半区间。

不同语言在能耗、时间和内存方面的标准化结果

还有 Stack Overflow 开发者调查。Rust 已连续多年是最受喜爱的语言。许多 RIIR 项目可能只是因为开发者想写 Rust 才存在。对此值得坦诚。

三种重写

并非所有重写都一样,明确谈的是哪一类会很有帮助。这里有三种类别。

可直接替换的实现目标是与原始程序在功能上完全一致。替换二进制文件,其他什么都不变。uutils coreutils、sudo-rs、作为容器运行时替代品的 youki,以及 Tor 的重新实现 Arti,都属于这一类。整个生态中有数千个这样的项目,从替换 libpng 这类小型文件格式库的 PNG crate,到背后有认真企业和社区资金支持的更大型基础设施项目。

替代方案解决同一个问题,但会做不同选择。用 ripgrep 代替 grep,用 delta 代替 diff,用 bat 代替 cat,用 Typst 代替 LaTeX,用 Polars 代替 pandas。它们并不试图成为完全相同的替代品。它们往往更快、更顺手,或者有不同的设计理念。Typst 很好地说明了可读性这一点:

LaTeX 与 Typst 的源代码对比

LaTeX 和 Typst 能产生相同的输出,但源代码讲的是完全不同的故事。至于纯性能,Marek 在一个 37GB 的 cargo target 目录中用 ripgrep 和 grep 搜索单词“cot”。grep 用时 52 秒,ripgrep 用时 6 秒。这不是边际差异。

grep 与 ripgrep 的性能对比

自身重写是现有项目决定用 Rust 重写自身的部分或全部,而不是替换一个外部二进制。Firefox、Linux 内核、Windows、Cloudflare 的基础设施和 Fish shell 都属于这里。这不是小赌注。如今世界上部署最广泛的一些软件已经包含 Rust,而它们就是通过这类路径走到今天的。

Rust 重写的性能:它真的有效吗?

有时有效。有时原因不太对。以 uutils 为例,sort 的速度几乎是 GNU sort 的四倍。原因是并行归并排序,Rust 的并发模型让它更容易正确实现。但另一些工具更快,只是因为它们是一次带着 30 年经验重新开始的重写。原项目不能随意试验,因为生产用户依赖它们。

uutils sort 与 GNU sort 的性能对比

PNG crate 是一个更能说明 Rust 特有收益的例子。Rust 实现的速度几乎是 libpng 的两倍。其中一部分来自自动向量化:Rust 编译器能从普通的 for 循环自动生成 SIMD 指令,而大多数 C 实现需要手写 SIMD。另一部分来自流式 DEFLATE 解压,它可以让更多数据同时装进 CPU 缓存。两者都是真正的 Rust 优势。

Rust 二进制体积:问题以及项目如何解决

Rust 二进制文件出了名地大,原因也确实存在:panic 处理代码、Debug trait 的实现、被编译进每个二进制的标准库、泛型产生的单态化,以及所有依赖的静态链接。

uutils 用 multicall 二进制格式解决了这个问题,BusyBox 采用的也是同一路径。所有工具被编译到一个二进制中,再通过符号链接调用。结果是:73MB 的独立二进制,变成一个 13.8MB 的 multicall 二进制,实际上比 GNU coreutils 标准安装的 18.4MB 还小。用 UPX 压缩后,体积降到 5MB。

uutils multicall 二进制体积对比

问题可以解决,但需要认真投入。

用 Rust 重写:会出什么问题,为什么?

这一部分讨论得还不够。每次重写都会引入新的 bug。你是从头写代码,这意味着不可避免会引入原项目里没有的新 bug 或回归。这不是 Rust 特有的问题,而是软件重写的问题。但值得清醒地说出来。

Cloudflare 曾在一个请求评分组件中引入 unwrap。uutils 的日期格式略有错误,导致无人值守升级失败。sudo-rs 在超时后把输入到一半的密码回显到了终端。Linux 内核 Rust 代码中的第一个 CVE,来自 Android Binder 驱动一个 unsafe 块里的竞态条件。TARmageddon 是 async-tar 中的一个远程代码执行漏洞,由 .tar 格式解析错误造成。

如果有大量资金和经验丰富团队支持的项目都会犯这些错误,我们也会。这不是不重写的理由,但这是认真对待测试的理由。

有时,Rust 根本不是正确选择。微软重写 TypeScript 编译器时选择 Go,很大程度上是因为 Go 的编程模型更接近 TypeScript;在代码库会长期同时包含两种语言的情况下,这一点很重要。NTPsec 选择 Go,是因为当时 Go 有更好的网络原语和更少碎片化的生态。这些都是合理选择,不是想象力的失败。

还有一些选择了 Rust 的重写也没有成功。Prisma 因技能缺口、部署复杂度和运行时问题,从 Rust 查询引擎迁回 TypeScript。Loglog Games 经过三年游戏开发后放弃 Rust。他们认为它很适合重构,却不适合迭代速度,并指出 Rust 游戏开发社区更关注引擎技术细节,而不是交付完成的游戏。curl/hyper 集成做到了 95%,随后因最后 5% 的困难和社区动力不足而被放弃。有意思的是,这次合作仍让两个项目受益:为了尝试集成而进行的过程,迫使两边都完成了清理。

许可证是一个真实的决策

RIIR 讨论中有一件事谈得不够:如果你在创建一个重新实现现有项目的新项目,许可证的选择会带来后果。

更严格的许可证,例如 GPL,可能会排除无法在专有项目中引入 copyleft 依赖的用户。更宽松的许可证也可能招致开源社区批评,有些人担心公司会使用代码却不回馈。没有放之四海而皆准的正确答案。这完全取决于项目目标和社区。但这是一项应该有意识做出的决定,而不是默认选择。

2026 年,RIIR 运动还在发生吗?

RIIR 这个梗有所消退,但实际的运动没有。Linux 内核中的 Rust 已不再是实验性功能,维护者在 2025 年维护者峰会上宣布实验成功。Rust 正在 Windows 内核中运行。Cloudflare、Firefox 和无数基础设施项目,都已将大量 Rust 代码投入生产。

规模是真实的。仅 Linux 和 Windows,Rust 就运行在数十亿台设备上。这可以说是“用 Rust 重写”这一想法迄今得到的最大验证。

怎样才能把它做好

如果你在考虑重写,我们建议先想清楚几件事。先确认它是否真的适合你的使用场景。问问你的代码库是否使用内存不安全语言,它是否是关键软件,是否有真实的性能和可靠性要求,以及是否有难以推理的大量并行或并发代码。你勾中的项越多,理由就越充分。

确认团队准备好了。要么他们已经懂 Rust,要么他们真心愿意学习并参与其中。Google 的数据表明,大约三分之二的开发者会在两个月内有信心向 Rust 代码库贡献代码。但这不是保证,重写的最后 5% 几乎总是比预期更难。小型重写需要几个月,中型重写需要一到两年,大型重写需要两到五年。它几乎总比你估计的时间长。

优先选择渐进式扩展,而不是彻底重写。在保持旧代码库运行的同时,加入用 Rust 写的新组件,几乎总比完整替换风险更低。你能拿到好处,却不用把整个项目押上去。

当你确实要重写时,建立一套严肃的测试套件。实践中最好的例子是 uutils:它运行官方 GNU coreutils 测试套件来追踪兼容性。截至 2026 年初,它们的通过率是 92.2%,还在上升。

uutils 与 GNU coreutils 测试套件的兼容性进度

那么,值得吗?

如果你的项目使用内存不安全语言,处理关键功能,有真实的性能要求,并涉及大量并发代码,答案是肯定的。重写有很强的理由,证据也支持它。

在这些条件之外,它仍可能值得,但分析需要更谨慎。热情可以理解,因为 Rust 确实很好。但它被设计为系统编程语言,而这正是它最擅长的地方。把 RIIR 当成每个性能或安全问题的默认答案,最后就可能得到一个耗时两年的重写项目:晚六个月交付,还引入了你早已修复过的 bug。

常见问题

RIIR 是什么意思?

RIIR 是 Rewrite It In Rust(用 Rust 重写)的缩写。它最初是开源 issue tracker 中的一项建议:为了内存安全和性能,把 C 和 C++ 项目迁移到 Rust;后来在 Rust 社区成为更广泛的文化梗。

用 Rust 重写软件值得吗?

这取决于你的情况。如果代码库使用内存不安全语言,处理关键功能,并且有真实的性能或并发需求,Rust 重写的理由很强。在其他情况下,收益没有那么明确,学习曲线、重写时间和新 bug 等成本都值得认真考虑。

用 Rust 重写有哪些风险?

每次重写都会引入新 bug,包括原项目已经修复的 bug。Rust 重写也要求开发者学习这门语言,耗时可能远超预期,还可能遇到平台支持、二进制体积以及与其他语言互操作方面的挑战。

迁移到 Rust 的最佳方式是什么?

渐进式扩展,而不是完全重写。在保持现有代码运行的同时,加入用 Rust 写的新组件。确实重写时,投入一套完整测试套件,验证新实现与原实现行为一致。

Rust 在 Linux 内核中成功了吗?

是的。在 2025 年 Linux Kernel Maintainers Summit 上,维护者的共识是 Rust 实验成功。Rust 现在是内核的核心组成部分,不再被视为实验性功能。


快得惊人,还是被吹得惊人?用 Rust 重写的现实检验
https://www.boer.xyz/posts/rewriting-in-rust-2026/
作者
boer
发布于
2026年8月20日
许可协议