|
| 1 | + |
| 2 | +--- |
| 3 | + |
| 4 | +# 🦀 Rust 编译速度优化 Cheatsheet |
| 5 | + |
| 6 | +> 适用于日常开发(Debug / 增量编译)场景,追求最短的 Edit → Compile → Run 循环。 |
| 7 | +
|
| 8 | +--- |
| 9 | + |
| 10 | +## 1️⃣ 更换链接器(效果最显著,必做) |
| 11 | + |
| 12 | +链接是编译最后一步,默认链接器很慢。更换后增量编译提速 **30%~60%**。 |
| 13 | + |
| 14 | +### Linux |
| 15 | + |
| 16 | +安装 `mold`: |
| 17 | + |
| 18 | +```bash |
| 19 | +# Ubuntu / Debian |
| 20 | +sudo apt install mold |
| 21 | + |
| 22 | +# Arch |
| 23 | +sudo pacman -S mold |
| 24 | + |
| 25 | +# Fedora |
| 26 | +sudo dnf install mold |
| 27 | +``` |
| 28 | + |
| 29 | +配置 `.cargo/config.toml`: |
| 30 | + |
| 31 | +```toml |
| 32 | +[target.'cfg(target_os = "linux")'] |
| 33 | +rustflags = ["-C", "link-arg=-fuse-ld=mold"] |
| 34 | +``` |
| 35 | + |
| 36 | +### macOS |
| 37 | + |
| 38 | +macOS 自带的链接器已经较快。如果追求极致,可尝试 `lld`: |
| 39 | + |
| 40 | +```toml |
| 41 | +[target.x86_64-apple-darwin] |
| 42 | +rustflags = ["-C", "link-arg=-fuse-ld=lld"] |
| 43 | + |
| 44 | +[target.aarch64-apple-darwin] |
| 45 | +rustflags = ["-C", "link-arg=-fuse-ld=lld"] |
| 46 | +``` |
| 47 | + |
| 48 | +### Windows |
| 49 | + |
| 50 | +推荐使用 `lld`(通常随 LLVM / Visual Studio 安装): |
| 51 | + |
| 52 | +```toml |
| 53 | +[target.x86_64-pc-windows-msvc] |
| 54 | +linker = "rust-lld.exe" |
| 55 | +``` |
| 56 | + |
| 57 | +> 💡 **全局生效**:把上述配置写入 `~/.cargo/config.toml`,所有项目自动使用。 |
| 58 | +
|
| 59 | +--- |
| 60 | + |
| 61 | +## 2️⃣ 使用 Cranelift 后端(Dev 构建提速) |
| 62 | + |
| 63 | +将 Debug 模式的代码生成后端从 LLVM 换成 Cranelift,**牺牲运行时性能换取编译速度**。 |
| 64 | + |
| 65 | +```bash |
| 66 | +# 安装 Cranelift 组件(需要 nightly) |
| 67 | +rustup component add rustc-codegen-cranelift-preview --toolchain nightly |
| 68 | +``` |
| 69 | + |
| 70 | +在 `Cargo.toml` 中配置: |
| 71 | + |
| 72 | +```toml |
| 73 | +[profile.dev] |
| 74 | +codegen-backend = "cranelift" |
| 75 | +``` |
| 76 | + |
| 77 | +运行时需要 nightly + unstable flag: |
| 78 | + |
| 79 | +```bash |
| 80 | +cargo +nightly -Z codegen-backend build |
| 81 | +``` |
| 82 | + |
| 83 | +> ⚠️ **注意**: |
| 84 | +> |
| 85 | +> - 仅用于 `dev` 构建,`release` 仍应使用 LLVM |
| 86 | +> - 生成的代码运行较慢(但开发阶段不在乎) |
| 87 | +> - 不支持所有 target 和特性(如 unwinding) |
| 88 | +
|
| 89 | +--- |
| 90 | + |
| 91 | +## 3️⃣ 优化 Dev Profile 配置 |
| 92 | + |
| 93 | +在 `Cargo.toml` 中对 Debug 构建进行调优: |
| 94 | + |
| 95 | +```toml |
| 96 | +[profile.dev] |
| 97 | +opt-level = 0 # 不做优化(默认,保持即可) |
| 98 | +debug = true # 保留调试信息 |
| 99 | +incremental = true # 确保增量编译开启(默认已开) |
| 100 | +codegen-units = 256 # 更多并行编译单元(牺牲运行时性能) |
| 101 | +lto = false # 不做链接时优化(默认,保持即可) |
| 102 | + |
| 103 | +# 让依赖库用稍高的优化级别(依赖不常改,编译一次受益多次) |
| 104 | +[profile.dev.package."*"] |
| 105 | +opt-level = 1 |
| 106 | +``` |
| 107 | + |
| 108 | +> 💡 `codegen-units = 256`(默认值)已经是 dev 模式最大值,不需要额外设置。 |
| 109 | +
|
| 110 | +--- |
| 111 | + |
| 112 | +## 4️⃣ 精简依赖特性(Feature Flags) |
| 113 | + |
| 114 | +**永远不要无脑使用 `features = ["full"]`**。 |
| 115 | + |
| 116 | +```toml |
| 117 | +# ❌ 错误示范:拉入所有功能,编译巨量无用代码 |
| 118 | +[dependencies] |
| 119 | +tokio = { version = "1", features = ["full"] } |
| 120 | + |
| 121 | +# ✅ 正确做法:只开启你用到的功能 |
| 122 | +[dependencies] |
| 123 | +tokio = { version = "1", features = ["rt-multi-thread", "macros", "net"] } |
| 124 | +``` |
| 125 | + |
| 126 | +常见"胖"依赖瘦身效果: |
| 127 | + |
| 128 | +| 依赖 | `full` 编译时间 | 精简后时间 | 节省 | |
| 129 | +|------|----------------|-----------|------| |
| 130 | +| `tokio` | ~15s | ~6s | ~60% | |
| 131 | +| `reqwest` | ~25s | ~10s | ~60% | |
| 132 | +| `serde` | ~4s | ~2s | ~50% | |
| 133 | + |
| 134 | +--- |
| 135 | + |
| 136 | +## 5️⃣ Cargo Workspace 拆分(中大型项目必做) |
| 137 | + |
| 138 | +将单体项目拆分为多个 crate,只有改动的 crate 会重新编译: |
| 139 | + |
| 140 | +``` |
| 141 | +my-project/ |
| 142 | +├── Cargo.toml # workspace 根 |
| 143 | +├── crates/ |
| 144 | +│ ├── core/ # 核心业务逻辑(很少改动) |
| 145 | +│ │ ├── Cargo.toml |
| 146 | +│ │ └── src/ |
| 147 | +│ ├── db/ # 数据库层(偶尔改动) |
| 148 | +│ │ ├── Cargo.toml |
| 149 | +│ │ └── src/ |
| 150 | +│ └── api/ # HTTP 接口层(频繁改动) |
| 151 | +│ ├── Cargo.toml |
| 152 | +│ └── src/ |
| 153 | +``` |
| 154 | + |
| 155 | +```toml |
| 156 | +# 根 Cargo.toml |
| 157 | +[workspace] |
| 158 | +members = ["crates/*"] |
| 159 | +``` |
| 160 | + |
| 161 | +> 💡 修改 `api` 层代码时,`core` 和 `db` 不会重新编译,增量编译飞快。 |
| 162 | +
|
| 163 | +--- |
| 164 | + |
| 165 | +## 6️⃣ 使用 `cargo check` 替代 `cargo build` |
| 166 | + |
| 167 | +日常写代码时,你只需要知道"代码有没有错",不需要真正生成可执行文件: |
| 168 | + |
| 169 | +```bash |
| 170 | +# ❌ 每次都完整编译(生成二进制,耗时长) |
| 171 | +cargo build |
| 172 | + |
| 173 | +# ✅ 只做类型检查和借用检查(跳过代码生成,快 2~5 倍) |
| 174 | +cargo check |
| 175 | +``` |
| 176 | + |
| 177 | +--- |
| 178 | + |
| 179 | +## 7️⃣ 后台持续检查工具 |
| 180 | + |
| 181 | +让编译在后台自动运行,你保存代码的瞬间就开始检查: |
| 182 | + |
| 183 | +### bacon(推荐) |
| 184 | + |
| 185 | +```bash |
| 186 | +cargo install bacon |
| 187 | +bacon # 默认运行 cargo check |
| 188 | +bacon run # 自动运行项目 |
| 189 | +bacon test # 自动跑测试 |
| 190 | +``` |
| 191 | + |
| 192 | +### cargo-watch |
| 193 | + |
| 194 | +```bash |
| 195 | +cargo install cargo-watch |
| 196 | +cargo watch -x check # 保存即检查 |
| 197 | +cargo watch -x run # 保存即运行 |
| 198 | +cargo watch -x 'test -- --nocapture' # 保存即测试 |
| 199 | +``` |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +## 8️⃣ SQLx 离线模式(用 SQLx 必做) |
| 204 | + |
| 205 | +`sqlx::query!` 宏在编译时连接数据库校验 SQL,非常慢。使用离线模式后读取本地缓存: |
| 206 | + |
| 207 | +```bash |
| 208 | +# 生成离线查询元数据 |
| 209 | +cargo sqlx prepare |
| 210 | + |
| 211 | +# 设置环境变量启用离线模式 |
| 212 | +export SQLX_OFFLINE=true |
| 213 | +``` |
| 214 | + |
| 215 | +会在项目根目录生成 `.sqlx/` 文件夹,把它提交到 Git 中,CI 也不需要连数据库了。 |
| 216 | + |
| 217 | +--- |
| 218 | + |
| 219 | +## 9️⃣ sccache 编译缓存(团队/CI 场景) |
| 220 | + |
| 221 | +跨项目、跨机器复用编译产物: |
| 222 | + |
| 223 | +```bash |
| 224 | +cargo install sccache |
| 225 | + |
| 226 | +# 设置环境变量(写入 shell profile) |
| 227 | +export RUSTC_WRAPPER=sccache |
| 228 | +``` |
| 229 | + |
| 230 | +效果: |
| 231 | + |
| 232 | +- 切换 Git 分支后重新编译 → **命中缓存,秒级完成** |
| 233 | +- CI 流水线多次构建 → **大幅缩短构建时间** |
| 234 | +- 团队共享远程缓存(支持 S3/GCS/Redis) |
| 235 | + |
| 236 | +--- |
| 237 | + |
| 238 | +## 🔟 其他实用技巧 |
| 239 | + |
| 240 | +### 减少过程宏依赖 |
| 241 | + |
| 242 | +```toml |
| 243 | +# 如果不需要 derive 宏,手动实现 trait |
| 244 | +serde = { version = "1", default-features = false } # 不自动拉 serde_derive |
| 245 | +``` |
| 246 | + |
| 247 | +### 使用 `cargo build --timings` 分析瓶颈 |
| 248 | + |
| 249 | +```bash |
| 250 | +cargo build --timings |
| 251 | +# 会生成 target/cargo-timings/cargo-timing.html |
| 252 | +# 用浏览器打开,可视化看到每个 crate 的编译时间 |
| 253 | +``` |
| 254 | + |
| 255 | +### 硬件层面 |
| 256 | + |
| 257 | +- 🔥 **SSD 是刚需**:Rust 编译是重 I/O 操作,机械硬盘体验极差 |
| 258 | +- 💾 **内存 ≥ 16GB**:大项目链接阶段内存消耗巨大 |
| 259 | +- 🧮 **多核 CPU**:Rust 编译天然支持多核并行,核越多越快 |
| 260 | + |
| 261 | +--- |
| 262 | + |
| 263 | +## 📋 Quick Setup(一键配置模板) |
| 264 | + |
| 265 | +将以下内容保存为项目的 `.cargo/config.toml`,即可获得开箱即用的优化体验: |
| 266 | + |
| 267 | +```toml |
| 268 | +# =========================================== |
| 269 | +# Rust 编译速度优化配置 |
| 270 | +# =========================================== |
| 271 | + |
| 272 | +# --- Linux: 使用 mold 链接器 --- |
| 273 | +[target.'cfg(target_os = "linux")'] |
| 274 | +rustflags = ["-C", "link-arg=-fuse-ld=mold"] |
| 275 | + |
| 276 | +# --- macOS: 使用 lld 链接器(可选) --- |
| 277 | +# [target.aarch64-apple-darwin] |
| 278 | +# rustflags = ["-C", "link-arg=-fuse-ld=lld"] |
| 279 | + |
| 280 | +# --- Windows: 使用 rust-lld --- |
| 281 | +# [target.x86_64-pc-windows-msvc] |
| 282 | +# linker = "rust-lld.exe" |
| 283 | + |
| 284 | +# --- 通用优化 --- |
| 285 | +[build] |
| 286 | +# 并行编译前端 jobs 数(默认为 CPU 核数) |
| 287 | +# jobs = 8 |
| 288 | + |
| 289 | +[term] |
| 290 | +# 彩色输出 |
| 291 | +color = "auto" |
| 292 | +``` |
| 293 | + |
| 294 | +配合 `Cargo.toml`: |
| 295 | + |
| 296 | +```toml |
| 297 | +[profile.dev] |
| 298 | +incremental = true |
| 299 | + |
| 300 | +# 依赖库用 opt-level=1 编译,提升运行时性能且只编译一次 |
| 301 | +[profile.dev.package."*"] |
| 302 | +opt-level = 1 |
| 303 | +``` |
| 304 | + |
| 305 | +--- |
| 306 | + |
| 307 | +## ⚡ 优化效果总览 |
| 308 | + |
| 309 | +| 优化手段 | 增量编译提速 | 全量编译提速 | 难度 | |
| 310 | +|---------|------------|------------|------| |
| 311 | +| 换 mold/lld 链接器 | ⭐⭐⭐⭐⭐ | ⭐⭐ | 简单 | |
| 312 | +| Cranelift 后端 | ⭐⭐⭐⭐ | ⭐⭐⭐ | 中等 | |
| 313 | +| `cargo check` 替代 build | ⭐⭐⭐⭐⭐ | — | 简单 | |
| 314 | +| bacon / cargo-watch | ⭐⭐⭐⭐ | — | 简单 | |
| 315 | +| 精简 Feature Flags | ⭐⭐⭐ | ⭐⭐⭐⭐ | 简单 | |
| 316 | +| Workspace 拆分 | ⭐⭐⭐⭐⭐ | ⭐⭐ | 中等 | |
| 317 | +| sccache 缓存 | ⭐⭐⭐ | ⭐⭐⭐⭐ | 简单 | |
| 318 | +| SQLx 离线模式 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 简单 | |
| 319 | +| `--timings` 分析瓶颈 | — | ⭐⭐⭐ | 简单 | |
| 320 | + |
| 321 | +**推荐优先级**:链接器 > cargo check/bacon > Feature 精简 > Workspace 拆分 > sccache > Cranelift |
0 commit comments