返回资讯中心
外部精选
软件工程
#开发者实时流

Hexcat 开发者分享 11 月提升 Rust 编译器性能的进展

来源标题:How to speed up the Rust compiler in November 2026

Hexcat 开发者发布了其从事 Rust 编译器性能优化首月的工作成果。核心改动是通过 PR #163857 用更简单高效的方案替换旧的 Span 压缩机制:增量构建中需要驻留(intern)的 Span 比例从 20-40% 降至约 1%,非增量构建则低于 0.1%。新方案还能在驻留情况下始终内联存储 context 字段。

Hacker News 最新dverlaeckt802026/11/5 · 今天17 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

我在Hexcat为Rust编译器性能工作的第一个月已经结束,是时候看看自上次发帖以来发生了一些什么。

Span是Rust编译器中的关键数据结构。每个AST、HIR和MIR节点都携带一个span。每个span有四个字段,分别记录以下信息。这四个字段各占32位,合计16字节数据。但大多数情况下,这16字节可以压缩为三种8字节内联格式之一,剩余情况则驻留(intern)到全局表中。其原理是利用数据中的规律:许多源位置的长度很小(即lo与hi之间的差值很小);许多span的context和/或parent为零,而非零的context和parent通常是较小的整数;parent仅在增量构建中使用。

#163857:在这个PR中,我用一种更简单、更高效的方案替换了旧的压缩方案。对于增量构建,我们现在通常只驻留约1%的span,而旧方案为20-40%。(在非增量构建中,我们通常驻留不到0.1%。)此外,即使在驻留情况下,我们也总能将context字段内联存储,这很有用,因为我们经常单独读取context。这一改动降低了众多基准测试的指令数,最佳情况下降幅超过3%,周期数的改善甚至更高。增量构建因驻留减少而获益最大。

#163971:在这个PR中,Josh Triplett利用新的表示形式对若干span操作进行了微优化。这降低了众多基准测试的指令数,最佳情况下降幅超过2%。

#164291:在这个PR中,我尝试使用模式类型为Span提供一个niche,使Option<Span>与Span大小相同。方案可行,但没有提升性能,因为我们很少使用Option<Span>,而且它让代码变得更复杂。因此我放弃了这一改动。

#163628:在元数据编码/解码和稳定哈希过程中,我们通常需要反复从哈希表中获取同一parent span的信息。在这个PR中,我在该哈希表前加了一个单条目缓存,从而在大多数情况下避免了哈希表查找。这降低了众多基准测试的指令数,最佳情况下降幅超过4%,主要惠及增量编译。

#163981、#164234、#165160:在这三个PR中,我聚焦于Diesel的编译时间——这个crate在开发中的新trait求解器比旧求解器更慢。我在三个PR中做了大约十几项微优化,例如热路径上的提前返回、避免分配、避免部分重复计算,以及优化一些特殊情况。这些改动将新求解器在Check Full构建上的指令数开销从1.49倍降至1.16倍,typenum和nalgebra等其他新求解器基准测试也有改善。还有更多工作要做,但这是不错的进展。

#164236:在这个PR中,我重新排列了一些代码,以避免在某个提前返回的场景中做不必要的工作,降低了众多基准测试的指令数,最佳情况下降幅超过4%。

#165022:在这个PR中,我移除了AttrTokenStream和AttrTokenTree类型。它们镜像了广泛使用的TokenStream和TokenTree类型,但仅用于cfg处理。这一改动主要是为了简化代码,但也避免了一些token流转换,降低了一系列基准测试的指令数:deep-vector压力测试降低4%,一些真实场景降低不到1%。

#164965:在这个PR中,我避免了在需要类型推断的字面量(如vec![1, 2, 3, 4])中为每个元素创建一个类型变量。这对包含超过100,000个元素的vec字面量的deep-vector压力测试是巨大的胜利(周期数降低8-12%)……但对其他任何基准测试都没有帮助。压力测试上的大胜利有时会转化为真实代码上的较小胜利,有时则不会。我最终还是合并了这个改动,因为它非常简单,而且确实改善了一个测试中的错误信息。

#164341:在这个PR中,我为处理强制转换(coercion)时的一个提前返回添加了一些额外情形。这降低了众多基准测试的指令数,多数降幅不到1%。

#165112:编译器中已有一个trivial_consts机制,对于const N: usize = 0这类平凡常量,它会跳过整个编译阶段(包括借用检查),以减少编译时间。在这个草案PR中,我扩展了该机制,使其也避免为这些常量构建MIR。最佳情况下(libc),它降低了最多6%的指令数,但trivial_consts本身已经很棘手且有些争议,因此前路尚不明确。更多细节见Zulip讨论串。

#164484:在这个PR中,Takayuki Maeda为元数据引入了一种稀疏编码机制。这略微增加了指令数,但周期数和实际耗时保持中性,更重要的是它将元数据大小降低了最多37%,最大RSS(峰值内存)降低了最多7%。

十月份我还前往代尔夫特参加了Hexcatconf,这是一个小型聚会,约有二十来人参加,来自Hexcat、RustNL及其他地方。旅途漫长,但非常值得!能与一些熟悉的面孔叙旧、结交新朋友、了解更多人正在做的事情,感觉很好。感谢Mara Bos组织这次活动。

2026-09-28至2026-11-02期间达到“相关”阈值的实际耗时测量结果可以在这里看到。一片绿色,45个基准测试中的236个测试有改善,其中不少达到两位数百分比,而仅3个基准测试中的4个测试出现回退。

如果将选择范围扩大到包含“非相关”结果(即低于方差阈值的结果),结果则略显混杂(599项改善对90项回退),这对于一个月这样相对较短的周期来说是意料之中的。总体而言,我们看到非常健康的平均实际耗时降低2.85%,并且

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →