Speed & Performance
Links:
- https://bencher.dev/learn/benchmarking/rust/criterion/
- https://bheisler.github.io/criterion.rs/book/criterion_rs.html
There are two major categories of software benchmarks: micro-benchmarks and macro-benchmarks. Micro-benchmarks operate at a level similar to unit tests. Macro-benchmarks operate at a level similar to integration tests.
Generally, it is best to test at the lowest level of abstraction possible. In the case benchmarks, this makes them both easier to maintain, and it helps to reduce the amount of noise in the measurements. However, just as having some end-to-end tests can be very useful for sanity checking the entire system comes together as expected, having macro-benchmarks can be very useful for making sure that the critical paths through your software remain performant.
std::time для быстрого замера
use std::time::Instant;
fn array_diff<T: PartialEq>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
a.into_iter().filter(|x| !b.contains(x)).collect()
}
fn array_diff2<T: PartialEq>(mut a: Vec<T>, b: Vec<T>) -> Vec<T> {
a.retain(|x| !b.contains(x));
a
}
fn main() {
let start = Instant::now(); // начало замера 1
println!("{:?}", array_diff(vec![1, 2, 2], vec![1]));
let duration_a = start.elapsed(); // конец
let start = Instant::now(); // начало замера 2
println!("{:?}", array_diff2(vec![1, 2, 2], vec![1]));
let duration_b = start.elapsed(); // конец
println!("Замеры: 1) {:?}; 2) {:?}", duration_a, duration_b);
}Для более точного замера следует собирать код с cargo run --release ключом.
Criterion
В Cargo.toml надо добавить зависимости:
[dev-dependencies]
criterion = "0.8"
[[bench]]
name = "my_benchmark"
harness = falseДалее в проекте создать папку и файл benches\my_benchmark.rs:
use criterion::{Criterion, criterion_group, criterion_main};
fn array_diff<T: PartialEq>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
a.into_iter().filter(|x| !b.contains(x)).collect()
} // функция 1 для проверки
fn array_diff2<T: PartialEq>(mut a: Vec<T>, b: Vec<T>) -> Vec<T> {
a.retain(|x| !b.contains(x));
a
} // функция 2 для проверки
fn benchmark_functions(c: &mut Criterion) {
let mut group = c.benchmark_group("Function Comparison");
group.bench_function("array_diff", |b| {
b.iter(|| {
std::hint::black_box(array_diff(vec![1, 2, 2], vec![1]));
}) // black_box блокирует оптимизации компилятора
});
group.bench_function("array_diff2", |b| {
b.iter(|| {
std::hint::black_box(array_diff2(vec![1, 2, 2], vec![1]));
})
});
group.finish();
}
criterion_group!(benches, benchmark_functions);
criterion_main!(benches);Для запуска тестов необходима команда cargo bench. Результаты замеров сохраняются и сравниваются с новыми результатами после внесения изменений.