Rust – 在 nightly 中使用并行前端加快编译速度

Rust 的编译器在 nightly 版本中引入了新的并行前端模式,旨在加速那些过去无法充分利用多核 CPU 的大型 crate 的编译。开发者报告的实际编译时间差异很大——从快速笔记本上的几乎瞬间构建,到大型 monorepo 的 20–30 分钟全量构建不等——这说明依赖数量、代码生成、链接器和硬件都会影响性能,也解释了为什么二进制依赖、替代后端、更快的链接器等进一步改进仍然重要。除了技术细节之外,很多评论也反映了 Rust 异常高的人气:用户称赞它的工具链、安全保证和“开发者体验”,而另一些人则质疑这种热度的强度,并将其与 Ruby、Go、Java 等更早期的语言浪潮进行比较。

rustc 中当前与新的并行性

  • 现有的并行性主要是在 crate 级别(每个 rustc 进程),而不是前端按文件/模块并行;LLVM 后端已经通过 codegen units 实现并行化。
  • 因此,大型单体 crate 无法充分利用多核机器;把项目拆成更多 crate 也有代价。
  • 新的 nightly 并行前端引入了 crate 内并行,并通过 jobserver 与 Cargo 协调,所以预计不会从 crate 级别构建中“抢走”并行度。
  • 该特性仍是实验性的:使用 -Z threads,可能死锁或卡住;默认是 1 个线程。

观察到的编译时间与影响因素

  • 体验差异很大:有人在快速笔记本上对小/中型项目几乎瞬间构建;也有人在大型 monorepo 上看到许多分钟的编译时间(数万到数十万 kLoC,数百个依赖)。
  • 依赖、proc-macros、代码生成(例如 protobuf),以及原生依赖(例如 zstd、librdkafka、OpenSSL)都被认为是耗时的主要来源。
  • 链接器的选择很重要:与默认链接器相比,mold 可以显著加快链接速度。
  • 网络文件系统相比本地磁盘会大幅拖慢构建。
  • 一些 monorepo 报告完全优化的 CI 构建需要 10–30 分钟,并消耗大量内存(例如开启 LTO 时 50GB)。

工具、优化思路与限制

  • rust-analyzer 往往比 rustc 更耗 CPU/RAM,但很多人认为这代价是值得的。
  • 对未来加速的建议包括:预编译/二进制依赖(尤其是构建脚本和 proc-macros)、用于快速开发构建的 Cranelift 后端、更好的链接器、以及 wasm 沙箱化的宏/构建脚本。
  • 有人认为剩余的大幅提升空间有限;编译器已经高度优化,而很多时间花在 LLVM/代码生成上,而不是借用检查。
  • 也有人认为整体仍有 2–3 倍的提升空间是现实的(例如通过二进制产物和替代后端),但由于语言复杂性和单态化,Rust 大概永远不会达到 Go 那样的编译速度。

CI、缓存与配置

  • 基于 Docker 的构建和短生命周期 CI runner 会使缓存更复杂,并可能增加耗时;不同团队会采用从激进复用缓存到定期清空缓存的不同策略。
  • 现在会使用 RUSTFLAGS="-Z threads=N" 或环境检测(nproc);未来稳定行为预计会与核心数和 jobserver 对齐。

Rust 的受欢迎程度与“营销”

  • 若干评论讨论了 Rust 为什么如此受追捧:人们长期以来对安全系统编程的需求、强大的工具链(Cargo/crates.io)以及相较于 C/C++ 更好的开发者体验。
  • 有人认为这种热情是真正的自下而上;也有人认为这是一种与过去浪潮类似的重复炒作周期(如 Ruby、Java、Go)。