如何在2026年7月加速Rust编译器
摘要
Nicholas Nethercote报道了Rust编译器近期性能改进,包括平均墙钟时间总体减少5.59%,rustdoc大幅加速总计28%,以及通过PR和PGO训练更改实现的显著Clippy优化。
<p><a href="https://lobste.rs/s/ycsivx/how_speed_up_rust_compiler_july_2026">评论</a></p>
查看缓存全文
缓存时间: 2026/07/31 06:44
# 如何在 2026 年 7 月加速 Rust 编译器
来源:https://nnethercote.github.io/2026/07/31/how-to-speed-up-the-rust-compiler-in-july-2026.html
我上一篇关于 Rust 编译器性能的文章是在 2025 年 12 月(https://nnethercote.github.io/2025/12/05/how-to-speed-up-the-rust-compiler-in-december-2025.html)。让我们看看从那之后发生了什么。
## 整体进展
2025-12-03 至 2026-07-29 期间的测量结果可以在这里(https://perf.rust-lang.org/compare.html?start=83e49b75e7daf827e4390ae0ccbcb0d0e2c96493&stat=wall-time&tab=compile&end=1a833e16546c2eb012758ddd499964fd8afee29e&nonRelevant=true)查看。
平均 wall-time 下降了 5.59%,这是一个不错的成绩。其中大约一半来自最近 rustdoc 的巨大改进,其平均 wall-time 下降了 37.92%!排除 rustdoc 的改动后,平均 wall-time 变化为 2.90%,这仍然是一个不错的结果。此外,Clippy 的速度也有重大改进,但目前 rustc-perf 在 CI 上并不会测量它。(更多内容见下文。)
## rustdoc
#159623(https://github.com/rust-lang/rust/pull/159623)、#159721(https://github.com/rust-lang/rust/pull/159721)、#159779(https://github.com/rust-lang/rust/pull/159779)、#159854(https://github.com/rust-lang/rust/pull/159854):在这些 PR 中,Noah Lev(https://github.com/camelid)大幅减少了处理 impl 时的工作量。我不会假装理解他到底做了什么更细节的事情(参见这里(https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/Is.20.60recursion_limit.60.20supposed.20to.20have.20cross-crate.20effects.3F)了解更多背景),但我知道它带来了许多两位数和一位数的 wall-time 百分比下降。Guillaume Gomez 说(https://mas.to/@[email protected]/117002726203860371)“这一切都是因为某人在使用 rustdoc 时遇到了一个奇怪的 bug”。
#159091(https://github.com/rust-lang/rust/pull/159091):在这个 PR 中,Jakub Beránek(https://github.com/Kobzol)将 rustdoc 基准测试加入了 PGO(https://en.wikipedia.org/wiki/Profile-guided_optimization)训练集,使得 rustdoc 能更好地利用 PGO。这使所有 rustdoc 基准测试的平均 wall-time 降低了 2.85%,最大降幅超过 6%。PGO 的设置很繁琐,但它确实能带来明显效果,而且训练集非常重要。
#157179(https://github.com/rust-lang/rust/pull/157179):在这个 PR 中,我改变了 rustdoc 对 impl 的排序方式。以前它会对包含 impl 名称的长 HTML 字符串进行排序;现在它使用一种更短的文本表示形式作为排序键。这在多个基准测试中减少了指令数,最好的情况下减少了 6% 以上。
下面这个图表展示了这些改进的综合效果,其横轴是所有 rustdoc 基准测试的相对 wall-time。
那是 28% 的下降!
#2515(https://github.com/rust-lang/rustc-perf/pull/2515):另一方面,在这个 PR 中,Jakub 在 rustc-perf 上启用了 rustdoc-json 基准测试。这将有助于提升使用 rustdoc JSON 输出的工具(如 cargo-semver-checks)的速度。
## Clippy
#17124(https://github.com/rust-lang/rust-clippy/pull/17124)、#17132(https://github.com/rust-lang/rust-clippy/pull/17132):在这两个 PR 中,xmakro(https://github.com/xmakro)对 Clippy 进行了大幅加速。Clippy 由数百个独立的 lint 组成,每个 lint 可以实现几十种 visitor 方法中的一种或多种:`check_item`、`check_stmt`、`check_expr` 等等。Clippy 会遍历 AST 和 HIR,并为每个节点调用该节点上每个 lint 对应的 `check_foo` 方法。每次调用都是虚拟分发。关键在于,这些调用大多数都是空操作,因为大多数 lint 只实现了少数几个 `check_foo` 方法(通常只有一个)。在这些 PR 中,xmakro 找到了一种合并传递的方法,使得空的 `check_foo` 方法(即绝大多数)不会被调用。
大约在同一时间,我也在调查这个完全相同的问题,并在 #157762(https://github.com/rust-lang/rust/pull/157762)中提出了一个略有不同的解决方案。我的解决方案在功能上是等价的,但代码改动不如 xmakro 的优雅,侵入性也更强。这个 PR 没有被合并,但我得到了更详细的测量结果(https://github.com/rust-lang/rust/pull/157762#issuecomment-4689980052):在大多数情况下,这使 Clippy 的运行时间减少了 10-30%!在真实世界的示例上,分支预测错误的次数减少了 20-80%,在一个压力测试中减少了 97%。如果你大量进行虚拟分发,其成本就会累积起来。
尽管我已经在 Rust 编译器性能方面工作了十年,但这是我第一次尝试优化 Clippy。我发现了一个严重的性能问题并修复了它,结果却发现别人比我早了几天的解决方案。我并不难过,因为更好的解决方案被合并了,但我仍然感到惊讶——这种事情的概率有多大?
## 增量编译
我们看到增量编译有一些小的改进。
#153122(https://github.com/rust-lang/rust/pull/153122):在这个 PR 中,Zalathar(https://github.com/Zalathar)改进了增量编译将磁盘缓存值提升到内存中的方式,在多个基准测试上减少了指令数,最好的情况下减少了 6%。
#153521(https://github.com/rust-lang/rust/pull/153521):这个 PR 同样是 Zalathar 对增量编译的调整,在多个基准测试上减少了指令数,最好的情况下减少了 2% 以上。
#154304(https://github.com/rust-lang/rust/pull/154304):在这个 PR 中,zetanumbers(https://github.com/zetanumbers)调整了 typeck 查询的工作方式,在多个基准测试上减少了指令数,最好的情况下减少了 6%。
#157781(https://github.com/rust-lang/rust/pull/157781):在这个 PR 中,xmakro 调整了增量编译,在多个基准测试上减少了指令数,最好的情况下减少了 5%。
#158794(https://github.com/rust-lang/rust/pull/158794):在这个 PR 中,xmakro 改进了依赖图读取的去重,在多个基准测试上减少了指令数,最好的情况下减少了 10%。
#159115(https://github.com/rust-lang/rust/pull/159115):在这个 PR 中,xmakro 再次改进了依赖图读取的去重,在多个基准测试上减少了指令数,最好的情况下减少了 6%。
## 新的 trait 求解器
目前大量工作正在推进,以让新的 trait 求解器(https://rust-lang.github.io/rust-project-goals/2025h2/next-solver.html)准备就绪。这其中包括性能工作。正在进行的项目很多,其中大部分我并不了解,但如果你有兴趣了解更多或提供帮助,这个 Zulip 线程(https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/perf.20triage/with/613396442)是一个很好的阅读起点。
下图展示了某个新的求解器基准测试的进展。
没错:这个基准测试的 wall-time 在过去三个月里从 27 秒降到了不到一秒。
#160005(https://github.com/rust-lang/rust/pull/160005):我会提到这个,因为它很有趣。lcnr(https://github.com/lcnr/)指出了一些 crate,在新的 trait 求解器下会出现非常大的性能下降。我使用 Cachegrind 对 rustc 编译它们进行了性能剖析,发现几乎一半的时间花在了 `memcpy` 上!这非常不寻常,但一旦发生这种情况,DHAT 的复制剖析(https://valgrind.org/docs/manual/dh-manual.html#dh-manual.copy-profiling)就会变得极其有用。有一个热门的 vector,其元素类型大小为 136 字节。LLVM 使用 `memcpy`(而不是生成的指令)来移动任何大小超过 128 字节的值。在这个 PR 中,我(a)避免了 2/3 的移动,并且(b)将类型缩小到 104 字节,使得剩余的移动不再使用 `memcpy`。这使得两个最糟糕 crate 的 wall-time 降低了 40%。
## 新的贡献者
最近性能相关的工作量有所增加,这是个好消息,我想重点介绍两位新人。第一位是 xmakro,在上文被提到了四次。第二位是 Arya Dradjica(https://github.com/bal-e),他是 Krabby(https://bal-e.org/speed/krabby/)的创造者,一个专注于速度的实验性 Rust 编译器。Arya 现在获得了财务支持(https://bal-e.org/speed/krabby/2026/rustnl-internship/),可以同时从事 Krabby 和 rustc 的工作。Arya 在 rustc 方面的工作目前主要集中在宏展开上,她已经做出了一些小的性能改进(例如 #158976(https://github.com/rust-lang/rust/pull/158976)、#158974(https://github.com/rust-lang/rust/pull/158974)和 #158577(https://github.com/rust-lang/rust/pull/158577)),并且她还有更多想法(https://github.com/rust-lang/rust/issues/159951)。如果你想了解她有多么热爱优化,可以看看她最近的 RustWeek 演讲(https://www.youtube.com/watch?v=SWRL4JpaR2I)。(剧透:非常热爱。)
## LLM
它们受到了很多关注,不是吗?好吧,关于这个就到此为止。
## AST
#158942(https://github.com/rust-lang/rust/pull/158942):在这个 PR 中,我通过移除一个字段缩小了一些 AST 节点的大小。移除的数据在需要时会临时存储在一旁。这主要带来了不到 1% 的指令数减少。
#158720(https://github.com/rust-lang/rust/pull/158720):前面的 PR 为这个 PR 铺平了道路,在这个 PR 中,我将 AST 表达式节点的大小从 72 字节缩小到了 64 字节。(足够小,可以放进一条缓存行。)表达式是迄今为止最常见的 AST 节点类型,这一变化减少了少数几个 AST 密集型基准测试的 wall-time,其中一些超过了 10%。这些基准测试的缓存未命中率下降了最多 29%。我记得几年前 AST 表达式节点还是 104 字节。好的性能往往来自于长期一点一点地削减。
#159266(https://github.com/rust-lang/rust/pull/159266):在这个 PR 中,我修改了属性的 AST 表示。这主要是为了代码清理,不过也确实带来了一些不到 1% 的指令数减少。
## 其他
#155678(https://github.com/rust-lang/rust/pull/155678):在这个 PR 中,aerooneqq(https://github.com/aerooneqq)将几个 HIR 级别的查询合并为一个,在多个基准测试上减少了指令数,最好的情况下减少了接近 3%。
## 性能分类
我想感谢那些轮流负责每周性能分类(https://github.com/rust-lang/rustc-perf/tree/main/triage/README.md)的人。这项工作包括查看过去一周所有影响性能(无论变好还是变坏)的已合并 PR,并收集额外信息以帮助隔离和修复性能回退。这是一项不引人注目、半自动化的任务,看起来似乎可以完全自动化,但我认为有人类参与是很重要的。
为什么?因为基准测试套件庞大而复杂,测量结果并不总是精确的,而且人类的参与可以很有说服力。PR 作者收到机器人发来的消息说“这个 PR 导致九个基准测试回退”是一回事。收到来自具有领域专业知识的人类发来的消息说“你可以忽略前四个,因为那些基准测试最近一直有噪声;你可以忽略接下来三个,因为回退太小,不显著;但你应当关注最后两个,因为它们是真实且显著的,可能由 `$REASON` 引起,你对如何改善这一点有什么想法吗?”则完全是另一回事。
所以,感谢当前的分诊团队:Mark Rousskov(https://github.com/mark-simulacrum)、Jonathan Brouwer(https://github.com/JonathanBrouwer)、Matyáš Racek(https://github.com/panstromek)和 Jakub Beránek(https://github.com/kobzol)。(50% 的捷克代表率可以通过变音符号看出来。)也感谢分诊团队的前成员:Felix Klock(https://github.com/pnkfelix)、Dylan MacKenzie(https://github.com/ecstatic-morse)和 Ryan Levick(https://github.com/rylev)。
## 最后一件事
一些个人消息:我最近从 VectorWare 辞职了。没什么戏剧性的;只是不太适合我。我现在正在寻找机会,回到 Rust 编译器方面的有偿工作。祝我好运吧!
相似文章
Rust语言的性能
本次演讲分析了Rust相较于C++的性能优势与劣势,提供了基准测试和最佳实践。附有幻灯片和阅读材料。
我们的Rust到Zig重写进展如何
Roc编译器团队已将他们30万行Rust代码库重写为Zig,经过18个月实现了功能对等,生成了更小的WebAssembly二进制文件并提高了性能。
只改一个函数,性能提升10倍?解读一个 Rust 性能 PR
一篇深度博文,通过基准测试复现和代码分析,解读 GreptimeDB 中让 Prometheus 读取转换速度提升 10 倍的 Rust 性能 PR。
将React编译器移植到Rust
一项将React编译器移植到Rust的计划,旨在提高性能并与Rust生态系统集成。
@tolgaogzz: 我和我的最佳 codex 将 eslint-plugin-svelte 移植到了 Rust,运行速度提升约 330 倍,所有规则的所有测试用例均通过…
一位开发者借助 Codex 将 eslint-plugin-svelte 移植到 Rust,实现了约 330 倍的速度提升,同时通过了所有测试用例。