Benches
test-r provides a simple benchmark runner as well, very similar to the built-in one in unstable Rust. The main differences are that test-r allows defining async bench functions too (when the tokio feature is enabled), and that benchmark functions also support dependency injection.
Defining benchmarks
To define a benchmark, just use the #[bench] attribute instead of a #[test] attribute on a function that takes a mutable reference to a Bencher:
#![allow(unused)] fn main() { use test_r::{bench, Bencher}; #[bench] fn bench1(b: &mut Bencher) { b.iter(|| 10 + 11); } }
The benchmark framework will measure the performance of the function passed to the iter method on the bencher.
If a benchmark needs shared dependencies, they can be added as additional parameters to the benchmark function. The &mut Bencher parameter must always be the first one.
#![allow(unused)] fn main() { use test_r::{bench, Bencher}; struct SharedDependency { value: i32, } #[bench] fn bench2(b: &mut Bencher, shared: &SharedDependency) { b.iter(|| shared.value + 11); } }
Async benchmarks
When the tokio feature is enabled, benchmarks can be async too. Just use the #[bench] attribute on an async function that takes a mutable reference to an AsyncBencher:
#![allow(unused)] fn main() { use test_r::{bench, AsyncBencher}; #[bench] async fn bench1(b: &mut AsyncBencher) { b.iter(|| Box::pin(async { 10 + 11 })).await; } }
Running benchmarks
Benchmarks are run by default as part of cargo test, but they can be also separately executed using cargo bench, or by passing the --bench flag to cargo test.