跳到主要内容

编译时优化

问题

如何通过编译器配置提升 Rust 程序性能?

答案

Release Profile 优化

Cargo.toml
[profile.release]
opt-level = 3 # 最高优化级别
lto = "fat" # 全程序链接时优化
codegen-units = 1 # 单代码生成单元(更好的优化)
panic = "abort" # 不生成 unwind 代码
strip = true # 去除符号
target-cpu = "native" # 针对当前 CPU 优化

优化选项详解

选项效果编译时间影响
opt-level0/1/2/3/s/z优化级别越高越慢
ltooff/thin/fat跨 crate 优化fat 很慢
codegen-units1~256并行编译粒度1 最慢但最优
panicunwind/abort栈展开方式abort 更小更快

PGO(Profile-Guided Optimization)

利用运行时数据指导编译器优化:

# 1. 编译插桩版本
RUSTFLAGS="-Cprofile-generate=/tmp/pgo" cargo build --release

# 2. 运行收集数据
./target/release/my-app # 使用典型工作负载

# 3. 合并数据
llvm-profdata merge -o /tmp/pgo/merged.profdata /tmp/pgo

# 4. 使用数据重新编译
RUSTFLAGS="-Cprofile-use=/tmp/pgo/merged.profdata" cargo build --release

PGO 通常能带来 10-20% 的性能提升。

编译时间 vs 运行性能

目标配置
最快编译opt-level = 0, lto = off, codegen-units = 256
平衡opt-level = 2, lto = "thin", codegen-units = 16
最佳性能opt-level = 3, lto = "fat", codegen-units = 1

常见面试问题

Q1: LTO 是什么?为什么能提升性能?

答案

LTO(Link-Time Optimization)在链接阶段对所有 crate 做跨模块优化,包括:

  • 跨 crate 内联
  • 跨 crate 死代码消除
  • 全程序常量传播

thin LTO 是折中方案:接近 fat LTO 的优化效果,但编译速度快很多。

Q2: target-cpu = "native" 有什么风险?

答案

编译出的二进制只能在当前 CPU 架构上运行。如果在 AVX-512 机器上编译,放到只有 AVX2 的机器上会 crash。分发给他人的程序不要使用此选项。

相关链接