性能调优实战
问题
Rust 程序的性能调优流程是什么?
答案
性能调优方法论
1. 建立基准线
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn bench_parse(c: &mut Criterion) {
let data = include_str!("../testdata/large.json");
c.bench_function("json_parse", |b| {
b.iter(|| {
serde_json::from_str::<serde_json::Value>(black_box(data)).unwrap()
})
});
}
criterion_group!(benches, bench_parse);
criterion_main!(benches);
2. Profile 定位热点
# 火焰图
cargo install flamegraph
cargo flamegraph --bin myapp
# 更精确的 CPU Profile
cargo install samply
samply record ./target/release/myapp
3. 常见优化手段
| 优化 | 手段 | 典型提升 |
|---|---|---|
| 减少分配 | String → &str,预分配 Vec | 2-5x |
| 避免序列化 | 零拷贝解析 | 3-10x |
| 并行化 | Rayon | 与 CPU 核数线性 |
| 缓存 | moka / HashMap | 10-100x |
| 更快的替代品 | simd-json 替代 serde_json | 2-4x |
| 内联 | #[inline] 关键函数 | 10-30% |
| 编译优化 | LTO + PGO | 10-20% |
4. 快速优化清单
// ❌ 慢:频繁分配
let result: Vec<String> = items.iter()
.map(|x| format!("item: {}", x))
.collect();
// ✅ 快:预分配
let mut result = Vec::with_capacity(items.len());
for x in &items {
result.push(format!("item: {}", x));
}
// ❌ 慢:String 拼接
let mut s = String::new();
for item in &items {
s = s + &item.to_string() + ", ";
}
// ✅ 快:使用 write!
use std::fmt::Write;
let mut s = String::with_capacity(items.len() * 20);
for item in &items {
write!(s, "{}, ", item).unwrap();
}
常见面试问题
Q1: Rust Release 编译已经很快了,还需要调优吗?
答案:
是的。Release 模式开启了编译器优化(-O2/O3),但算法复杂度、内存分配模式、IO 策略等不会被编译器自动优化。常见的调优空间:
- 算法选择:O(n²) → O(n log n)
- 内存分配:减少 malloc/free 次数
- IO 模式:批量 IO 代替逐条
- 并行化:利用多核