← 文章 / 编程开发
Hacker News 2小时前 · 2026-10-01 23:26:35 · 3 阅读

2026年9月加速 Rust 编译器的方法

我上一篇关于 Rust 编译器性能的文章发布于两个月前,这期间发生了不少事。

总体进展

2026-07-29 至 2026-09-28 这段时间的性能数据可以在这里查看。

平均墙钟时间减少了 4.57%,短短两个月能有这样的进步相当可观。629 项基准测试中有 555 项得到改善,只有 74 项出现回退,不少基准测试的降幅达到了两位数百分比。用技术术语来说,这个结果就是“一片绿海”。

rustdoc

上一篇文章里我提到 Noah Lev 在 rustdoc 上取得了巨大的性能提升。他最近写了一篇文章,详细讲解了具体做法,读起来既有趣又令人满意。

Clippy

#159642:在这个 PR 中,Jakub Beránek 为 Clippy 启用了 PGO,让大多数 Clippy 基准测试的墙钟时间都有所下降,最好情况下提升了 18%!

LLVM 升级

#158734:在这个 PR 中,Nikita Popov 把编译器使用的 LLVM 升级到了 LLVM 23。和往常一样,每次升级 LLVM 都能带来不错的提速:所有基准测试的墙钟时间平均减少 1.2%,听起来不多,但对单个 PR 来说已经非常惊人了。LLVM 团队干得漂亮!

新的借用检查器

新的借用检查器 Polonius Alpha(与 拿破仑 Dynamite 毫无关系)已 在 Nightly 渠道启用。 它比现有的借用检查器更精确,能接受一些旧检查器会拒绝的合法程序。不过,它的计算量也更大,在少数情况下(例如流行的 serde crate)对编译时间产生了可测量的影响。幸好,Jack Huey 已经着手优化。

#161938:在这个 PR 中,Jack 将部分活性计算改为惰性执行,使 serde 的指令数减少了 3-5%,其他一些基准测试也减少了不到 1%。

#163027:在这个 PR 中,Jack 调整了数据结构并微调了内联,使众多基准测试的指令数减少了不到 1%。

要消除 Polonius Alpha 剩余的回归问题,还需要进一步工作。但值得注意的是,“绿色海洋”(全面测试通过的态势)表明,这些回归已被近期大量的其他改进所掩盖。

新的 Trait 求解器

新的 trait 求解器 Penelope Hammertime, [编者注:这名字靠谱吗?] 也已在 Nightly 渠道启用。

正如我所说的,最近发生了很多事。

与新的借用检查器类似,新的 trait 求解器在少数情况下速度较慢。Jana Dönszelmann 撰写了一篇详细文章,介绍了提升该新求解器性能的努力。

Jana 的文章已经写得足够详细,因此关于新求解器正在进行的各项工作,我就不再多说什么了,只顺带提一下我提交的那些 PR: #160479、 #160605、 #160801、 #160892、 #161077, 以及 #161211。 其中部分 PR 显著缩短了某些异常耗时的 crate 的编译时间:这里有 50% 的降幅,那边有 25% 的降幅,还有 15% 的降幅,甚至在某个压力测试中下降幅度更大。而且,不只有我一个人在这方面取得了进展……去读读 Jana 的文章吧。

xmakro

新贡献者 xmakro 继续保持良好的优化势头。

#157281:在这个 PR 中,xmakro 优化了构建 specialization 图时的 impl 处理。这使得所有基准测试的平均 cycle count 减少了 1.58%,对于单个 PR 来说,这是一个巨大的提升。

#158059:在这个 PR 中,xmakro 优化了增量编译数据加载的一个方面,在多个基准测试中降低了指令数,最佳情况下降低了 6%。

#160473:在这个 PR 中,xmakro 避免了在热 obligations 处理路径中的一些内存分配,在多个基准测试中降低了指令数,最佳情况下降低了 2%。

#160268:在这个 PR 中,xmakro 通过将新旧 trait solver 选择代码从动态调度改为静态调度,避免了大量内存分配。这在许多基准测试中使指令数降低幅度大多在 1% 以内。这条热分配路径长期以来一直出现在性能剖析中,我之前曾在#155714中尝试过完全相同的思路。但我在几个基准测试中遇到了性能回退,可能是因为某些 #[inline] 属性的放置位置略有不同。很高兴看到这种明显的低效问题终于得到修复。

Dataflow 分析

#160193:这个 PR 更改了编译器中数据流分析所用的 CFG 遍历算法。这些分析需要迭代到不动点,遍历算法会影响收敛速度。对大多数代码来说新算法没什么区别,但 cranelift-codegen 这个 crate 里有一个超过 18,000 个基本块的巨型函数。旧算法为借用检查器所用的 EverInitializedPlaces 分析达到不动点需要调用 apply_effects_in_block 150 万次,新算法只需 9 万次。这使得该 crate 的 check 构建在耗时上降低了约 30%。

#160033:这个 PR 进一步优化了 EverInitializedPlaces,这次是不再为 projection 跟踪不必要的数据。match-stress 基准的指令数因此减少 17%,另外几个基准减少不到 1%。

LLM

LLM 在某些分析任务上已经很强了。我依然坚持自己写所有代码和文字,因为(a)这至关重要,(b)项目政策也这样要求,不过本文提到的几个 PR 里 LLM 的分析辅助确实帮了忙。

好了,这个话题到此为止。

杂项

#160535:这个 PR 中,Chris Denton 增大了编译器的默认栈大小,从而移除了 ensure_sufficient_stack——这是一种手动扩栈机制,散布在递归深度可能很大的各处代码里。这个改动引发了大量讨论,因为如何妥善处理栈耗尽并不容易决定。但性能收益很明确:多个基准的指令数都有下降,最好的情况接近 3%。

#160506:项目经常使用“rollup”PR,即把多个 PR 合并在一起提交。这是因为我们的 CI 容量不足,无法单独合并每一个 PR。通常影响性能的 PR 会单独合并,以便清晰衡量其效果。但破天荒的一次,当时合并队列里积压了大量性能优化 PR,Jonathan Brouwer 索性创建了一个包含 10 个性能优化 PR 的 rollup 来推动进度!这是令人高兴的“烦恼”。随后还出现了 #162859,里面打包了 4 个性能优化 PR。(不用担心意外副作用混入,因为合并后我们可以对每个单独的 PR 运行性能基准测试套件,确保每个 PR 都达到了预期的性能效果。)

#162747:在这个 PR 中,我对将 AST 降级为 HIR 的代码做了一些细微改进。原本这是一次清理工作,没期待会影响性能,结果它在多个基准测试中降低了指令数,最佳情况下减少了 1.5%。有时候运气就是这么好。

项目进展

明天我将开始加入 Hexcat,从事 编译器性能优化 项目目标的工作。令人兴奋!衷心感谢 Mara Bos、Predrag Gruevski 以及其他促成此事的所有人。

编者后记

新求解器的名字并不是 Penelope Hammertime;那只是个玩笑。

作者后记

它的真名是 Pineapple Häagen-Dazs。

原始来源: Hacker News

评论 (0)