2.6-带输入的基准测试
对不同输入规模进行基准测试
译文 · 基于 Criterion.rs Documentation
原文链接: https://bheisler.github.io/criterion.rs/book/user_guide/benchmarking_with_inputs.html
Criterion.rs 可使用一个或多个不同输入值运行基准测试,以研究性能如何随输入变化。
若函数只有一个输入,可使用 Criterion 结构体上的简单接口运行该基准测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};
fn do_something(size: usize) {
// 使用 size 做某事
}
fn from_elem(c: &mut Criterion) {
let size: usize = 1024;
c.bench_with_input(BenchmarkId::new("input_example", size), &size, |b, &s| {
b.iter(|| do_something(s));
});
}
criterion_group!(benches, from_elem);
criterion_main!(benches);
|
这样很方便:会自动将输入经 black_box 传递,无需直接调用。还会在基准描述中包含 size。
Benchmarking With A Range Of Values
Criterion.rs 可使用 BenchmarkGroup 比较函数在一系列输入上的性能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| use std::iter;
use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::Throughput;
fn from_elem(c: &mut Criterion) {
static KB: usize = 1024;
let mut group = c.benchmark_group("from_elem");
for size in [KB, 2 * KB, 4 * KB, 8 * KB, 16 * KB].iter() {
group.throughput(Throughput::Bytes(*size as u64));
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
b.iter(|| iter::repeat(0u8).take(size).collect::<Vec<_>>());
});
}
group.finish();
}
criterion_group!(benches, from_elem);
criterion_main!(benches);
|
本示例对将产生 N 字节序列的迭代器 collect 到 Vec 的耗时做基准测试。首先创建基准组,告诉 Criterion.rs 一组基准彼此相关;Criterion.rs 会为基准组生成额外摘要页。然后在所需输入集合上迭代;也可以手动展开循环、生成特定大小的输入等。
在循环内调用 throughput,告知 Criterion.rs 每次迭代处理 size 字节,用于估计每秒可处理的字节数。接着调用 bench_with_input,提供唯一基准 ID(此处仅为 size,也可按需生成自定义字符串),传入 size 以及接受 size 与 Bencher 并执行实际测量的闭包。
最后 finish 基准组,为该组生成摘要页。建议显式调用 finish;若忘记,在组被 drop 时会自动调用。

可见迭代器长度与 collect 到 Vec 的耗时大致呈线性关系。