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
.