跳到主要内容

基准测试

问题

如何对 Rust 代码进行可靠的基准测试?

答案

criterion(推荐)

benches/my_bench.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};

fn fibonacci(n: u64) -> u64 {
match n {
0 | 1 => n,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}

fn fibonacci_iter(n: u64) -> u64 {
let (mut a, mut b) = (0u64, 1u64);
for _ in 0..n {
let t = a + b;
a = b;
b = t;
}
a
}

fn bench_fibonacci(c: &mut Criterion) {
let mut group = c.benchmark_group("fibonacci");

for n in [10, 20, 30] {
group.bench_with_input(BenchmarkId::new("recursive", n), &n, |b, &n| {
b.iter(|| fibonacci(black_box(n)))
});
group.bench_with_input(BenchmarkId::new("iterative", n), &n, |b, &n| {
b.iter(|| fibonacci_iter(black_box(n)))
});
}
group.finish();
}

criterion_group!(benches, bench_fibonacci);
criterion_main!(benches);
cargo bench                    # 运行基准测试
cargo bench -- fibonacci/20 # 只运行特定测试

关键注意事项

陷阱解决方案
编译器优化掉代码使用 black_box()
不稳定的结果criterion 自动统计(置信区间)
profile 不同bench 自动用 release
系统噪声多次运行取平均
black_box 的作用

black_box 告诉编译器"这个值可能被外部使用",防止编译器优化掉整个计算。没有 black_box 的基准测试结果可能是 0ns(被优化掉了)。


常见面试问题

Q1: criterion 比标准库的 bench 好在哪?

答案

特性criterion#[bench](nightly)
Stable Rust❌ 需要 nightly
统计分析置信区间、回归检测仅平均值
HTML 报告
对比基线✅ 自动对比上次

相关链接