跳到主要内容

编译时间优化

问题

Rust 编译太慢怎么办?有哪些优化手段?

答案

编译时间分析

# 查看各 crate 编译时间
cargo build --timings
# 生成 cargo-timing.html 报告

# 逐步分析
cargo build -Z timings # nightly

优化清单

优化手段效果说明
开发时用 debug 编译显著不要在开发时用 --release
减少泛型单态化中等大型泛型函数提取非泛型部分
减少 derive 宏中等只 derive 需要的 trait
使用 workspace中等并行编译独立 crate
mold/lld 链接器显著替代默认链接器
sccache显著编译缓存,跨项目复用
cargo-nextest显著更快的测试运行器

快速配置

.cargo/config.toml
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

[target.x86_64-apple-darwin]
rustflags = ["-C", "link-arg=-fuse-ld=/opt/homebrew/bin/ld64.lld"]

# 开发时优化级别
[profile.dev]
opt-level = 0
debug = true

# 依赖用更高优化级别(编译一次即可)
[profile.dev.package."*"]
opt-level = 2

减少泛型膨胀

// ❌ 每个不同的 T 都会生成一份代码
fn process<T: Display>(items: &[T]) {
for item in items {
println!("{}", item);
// ... 大量逻辑
}
}

// ✅ 提取非泛型部分
fn process<T: Display>(items: &[T]) {
for item in items {
process_inner(&item.to_string());
}
}

fn process_inner(s: &str) {
println!("{}", s);
// ... 大量逻辑(只编译一次)
}

常见面试问题

Q1: Rust 编译为什么慢?

答案

  1. 泛型单态化:每个具体类型生成独立代码 → 编译代码量大
  2. 宏展开:过程宏(如 serde derive)可能生成大量代码
  3. LLVM 后端:优化阶段(特别是 LTO)非常耗时
  4. 借用检查:复杂的生命周期分析
  5. 链接:默认链接器慢(换 mold 可大幅改善)

最有效的优化:mold 链接器 + sccache + workspace 拆包

相关链接