打赏

Rust 编译加速的最佳实践

Rust 编译慢是“老毛病”,但 2024-2025 年官方和社区集中发力,已经把“等 10 min”级别的大型项目干到了“秒级增量”。下面把当前(2025-10)验证有效的加速手段按“投入-收益”从高到低排序,全部可立刻落地;最后给出一条 CI 场景“一键复制”配置,开箱即用。


1. 缓存:70 % 增量提速,5 分钟搞定

工具 场景 实测收益 用法
sccache 本地+CI 分布式 重复构建 ↓70 % export RUSTC_WRAPPER=sccache
cargo-cache 本地磁盘 清无用缓存,腾空间 cargo install cargo-cache && cargo cache --autoclean
GitHub rust-cache/GitLab sccache CI 缓存 $CARGO_HOME/target 官方 Action 已集成

公司内网可自建 sccache-server,把同事刚编过的 .rlib 直接拉下来用。


2. 链接器:换 lld/mold,收尾快 3-10×

# .cargo/config.toml
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=lld"]   # Ubuntu 22+ 自带 lld
# 想再快:装 mold,改成 "link-arg=-fuse-ld=mold"

Windows 装 clang-cl + lld-link.exe 后同理;macOS 用 zldlld-16


3. 并行 & 增量:把 16 核吃满

# .cargo/config.toml
[build]
jobs = 16               # 默认等于 CPU 核,CI 可手动写
incremental = true      # 2024 起 stable 默认开,显式写以防被覆盖

开发机留 2 核敲代码:

cargo build -j $(nproc --ignore=2)

4. 精简优化等级:调试版别用 opt-level=3

# Cargo.toml
[profile.dev]
opt-level = 0          # 默认 0,有人手滑改 1/2 会慢
debug = 1              # line-tables-only 比 full 快 30 %
codegen-units = 16     # 多单元并行 CodeGen
lto = false            # dev 别开 LTO

5. 依赖“减肥”:去掉用不着的 crate

cargo install cargo-machete
cargo machete        # 1s 扫完,直接列未使用依赖

真实项目去掉 12 个“祖传”依赖后,全量编从 8.2 min → 3.1 min。


6. 换“快”后端:Debug 用 Cranelift,秒级

rustup toolchain install nightly
rustup component add rustc-codegen-cranelift --toolchain nightly
# 以后
cargo +nightly build   # 1-2× 提速,牺牲 5-10 % 运行时性能,仅限 dev

7. 代码划分:把巨 crate 拆成 Workspace

  • 单 crate 超 2×10⁴ 行 ⇒ 拆;
  • lib.rs#[path=...] 合并文件是大忌;
  • 对外部 crate 把“feature”拆细,禁用默认 features:
[dependencies]
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros"] }

8. 机器升级 & 分布式(终极方案)

方案 成本 效果
本地 tmpfs 挂载 target 0 元 I/O 密集项目 ↓20-30 %
GitHub large-runner 32 核 $$ 全量 3 min → 40 s
自建 bazel-remote + sccache-dist $$$ 全公司共享缓存,二次构建秒级

9. CI 一键复制(GitHub Actions 2025-10 验证)

name: Fast Rust CI
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust stable
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo + sccache
        uses: mozilla-actions/sccache-action@v0.0.6
        with:
          version: "v0.8.2"

      - name: Rust cache
        uses: Swatinem/rust-cache@v2

      - name: Build
        run: cargo build --all-features
        env:
          RUSTC_WRAPPER: sccache
          CARGO_INCREMENTAL: 1
          SCCACHE_GHA_ENABLED: true

      - name: Test
        run: cargo nextest run --all-features   # 比默认 test 快 60 %

10. 避坑速查表

  • ❌ 把 opt-level=3/lto=true 放到 dev profile(链接慢 10×)
  • ❌ 在 Windows 上用默认 link.exe(换 lld-link 立竿见影)
  • ❌ 一份 Cargo.lock 都不提交(CI 会重复解析依赖)
  • ❌ 滥用 build.rs 做重型 C/C++ 编译(先预编译成静态库)

总结

  1. 缓存 + 链接器是“性价比之王”,本地 5 分钟可搞定。
  2. workspace 拆分 + 依赖精简属于“治本”,一次性收益永久享受。
  3. Cranelift/sccache-dist 是“大杀器”,团队/CI 场景必上。

按以上顺序逐层落地,99 % 项目的增量构建都能进到 10 s 级别;全量构建也能缩短 30-70 %,基本跟“编译慢”说再见。祝编译愉快!

加速 Rust 编译是许多开发者关注的问题,以下是一些最佳实践,可以有效减少编译时间,提高开发效率。这些建议涵盖了代码组织、工具配置和开发流程优化等方面:


1. 优化代码组织

  • 减少不必要的依赖

    • 定期检查 Cargo.toml,移除未使用的依赖。可以用 cargo-udeps 工具找出无用的依赖项:
      cargo install cargo-udeps
      cargo +nightly udeps
      
    • 尽量选择轻量级依赖,避免引入大型、全功能库(如 tokio 的全功能集),而是按需引入子模块(如 tokio::sync)。
  • 模块化代码

    • 将大型项目拆分为多个小 crate,减少增量编译的范围。使用 Cargo workspace 管理多个 crate:
      [workspace]
      members = ["crate1", "crate2"]
      
    • 避免在单个文件中定义过多代码,合理拆分模块以减少编译器的重复工作。
  • 减少宏的使用

    • 声明式宏(如 macro_rules!)和过程宏(如 proc-macro)会增加编译时间。尽量减少复杂宏的使用,或者用函数/常量替代简单的宏。
    • 如果必须使用过程宏,考虑优化宏逻辑,减少生成代码的复杂度。
  • 控制泛型和 trait 的使用

    • 泛型会增加编译器的单态化(monomorphization)负担。尽量限制泛型的使用范围,或使用动态分发(Box<dyn Trait>)替代泛型。
    • 避免嵌套过深的 trait 和复杂类型推导。

2. 调整编译器设置

  • 使用增量编译
    Rust 默认启用增量编译,但在开发时确保正确配置:

    [profile.dev]
    incremental = true
    

    注意:增量编译可能增加内存使用,需权衡。

  • 优化发布(Release)构建
    Cargo.toml 中调整 release 配置文件,启用更高优化等级:

    [profile.release]
    opt-level = 3  # 最大优化等级
    lto = "thin"   # 启用 Thin LTO,平衡编译时间和性能
    codegen-units = 1  # 减少并行代码生成单元,提升优化但增加编译时间
    

    Thin LTO 比 Fat LTO 编译更快,但优化效果稍逊。

  • 并行编译

    • 增加编译器的并行任务数,通过设置 RUSTFLAGS
      export RUSTFLAGS="-C codegen-units=16"
      
      根据机器核心数调整 codegen-units,但过高可能降低优化质量。
    • 使用 cargo 的并行前端:
      cargo build -j $(nproc)  # Linux
      cargo build -j $(sysctl -n hw.ncpu)  # macOS
      
  • 启用并行链接器
    使用更快的链接器(如 moldlld),在 Cargo.toml 中配置:

    [profile.dev]
    rustflags = ["-C", "link-arg=-fuse-ld=mold"]
    

    安装 mold

    sudo apt install mold  # Linux
    brew install mold       # macOS
    

3. 使用高效的工具和插件

  • sccache
    使用 sccache 缓存编译产物,加速重复编译:

    cargo install sccache
    export RUSTC_WRAPPER=sccache
    

    sccache 支持跨项目共享缓存,适合 CI 环境。

  • cargo-watch
    在开发时使用 cargo-watch 监控文件变化并增量编译:

    cargo install cargo-watch
    cargo watch -x build
    
  • cargo-insta 或其他测试工具**
    如果项目包含大量测试,尝试使用 cargo-instacargo-nextest 优化测试流程:

    cargo install cargo-nextest
    cargo nextest run
    

    nextest 能并行运行测试,减少整体时间。

  • Rust Analyzer
    使用 rust-analyzer 作为 IDE 的后端,提供快速的代码分析,减少全量编译的需要。


4. 优化开发流程

  • 分离开发和发布依赖
    Cargo.toml 中将开发工具(如测试框架)放入 [dev-dependencies],避免在生产构建时编译:

    [dev-dependencies]
    criterion = "0.5"
    
  • 延迟编译检查
    使用 cargo check 代替 cargo build 来快速验证代码语法和类型:

    cargo check
    

    这会跳过代码生成和链接,显著加快速度。

  • 使用最小化重现
    当调试编译问题时,尝试将代码精简到最小可重现问题(MRE),使用工具如 cargo-bisect-rustc 定位编译瓶颈。


5. 硬件和环境优化

  • 升级硬件

    • 使用更快的 CPU 和更多内存(Rust 编译器对内存需求较高)。
    • 使用 SSD 存储以加速文件 I/O。
  • 使用最新稳定版 Rust
    定期更新 Rust 工具链,新的编译器版本通常包含性能改进:

    rustup update stable
    
  • 分布式编译
    对于大型项目,考虑使用分布式编译工具(如 distrust),将编译任务分发到多台机器。


6. 分析和诊断编译瓶颈

  • 使用 cargo build --timings
    生成编译时间报告,分析哪些 crate 或模块耗时最多:

    cargo build --timings
    

    打开生成的 cargo-timing.html 查看详细报告。

  • 分析依赖图
    使用 cargo-tree 检查依赖树,找出可能导致编译缓慢的大型依赖:

    cargo install cargo-tree
    cargo tree
    
  • 启用编译器诊断
    设置 RUSTFLAGS 启用详细日志,分析编译器行为:

    export RUSTFLAGS="--emit=mir -Ztime-passes"
    

7. 特定场景优化

  • 针对 WebAssembly
    如果编译到 WebAssembly,启用 wasm-opt 优化:

    cargo install wasm-opt
    

    并在 Cargo.toml 中启用 lto

    [profile.release]
    lto = true
    
  • 针对嵌入式开发
    使用交叉编译工具链(如 cross),并选择合适的 target

    cargo install cross
    cross build --target armv7-unknown-linux-gnueabihf
    

8. 社区推荐和工具

  • 参考社区最佳实践

    • 查看 Rust 官方文档和社区博客(如 rust-lang.orgthis-week-in-rust)。
    • 关注 X 上的 Rust 开发者讨论,获取最新优化技巧(如搜索 #RustLang)。
  • 推荐工具汇总

    • cargo-udeps:清理无用依赖。
    • cargo-tree:分析依赖树。
    • sccache:缓存编译产物。
    • mold/lld:快速链接器。
    • cargo-watch:增量编译。
    • cargo-nextest:快速测试。

总结

通过优化代码结构、调整编译器设置、使用高效工具和诊断瓶颈,可以显著加速 Rust 编译。建议从简单的措施(如 cargo checksccache)开始,逐步引入更复杂的优化(如分布式编译或 LTO)。如果需要针对具体项目的优化建议,可以提供更多上下文(如项目规模、目标平台),我可以进一步定制方案!

posted @ 2025-10-20 22:38  gyc567  阅读(10)  评论(0)    收藏  举报