Edit:
I've left the post as it was below but I thought I'd share how I eventually solved my issue in a way I was completely satisfied with, which was by creating a blocking async handle in which to run the async function I wanted to benchmark.
async fn do_something(l: &mut NonClonableType) {
l.method_requiring_mutable_ref().await.unwrap();
}
fn my_benchmarks(c: &mut Criterion) {
c.bench_function("help_needed", |b| {
b.iter_batched_ref(
|| {
let data = "some_data";
let mut non_clonable_type = NonClonableType::new();
type.set_some_data(data);
non_clonable_type
},
|input| {
let rt = Runtime::new().unwrap();
let handle = rt.handle();
handle.block_on(async move { do_something(input).await.unwrap() })
},
BatchSize::SmallInput,
);
});
}
I'm trying to use criterion
to benchmark an async
method on a struct that requires self
be &mut
, and that is part of a trait using async_trait
.
Here's my benchmark code:
use criterion::BatchSize;
use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};
use criterion::async_executor::FuturesExecutor;
// Here we have an async function to benchmark
async fn do_something(l: &mut NonClonableType) {
l.method_requiring_mutable_ref().await.unwrap();
}
fn my_benchmarks(c: &mut Criterion) {
let mut group = c.benchmark_group("Help!");
group.bench_function(BenchmarkId::new("help_needed: {}", "details"), |b| {
b.to_async(FuturesExecutor).iter_batched_ref(
|| -> NonClonableType {
let data = "some_data";
let mut non_clonable_type = NonClonableType::new();
type.set_some_data(data);
non_clonable_type
},
|nct: &mut NonClonableType| do_something(nct),
BatchSize::SmallInput,
)
});
}
criterion_group!(benches, my_benchmarks);
criterion_main!(benches);
Part of what I did there was inspired by frequent solver of people's problems Kevin Reid's responses to this StackOverflow question, where Kevin suggests using .iter_batched_ref
.
The error I'm getting has come up in other posts, namely:
error: lifetime may not live long enough
--> project/benches/my_benchmarks.rs:28:39
|
28 | |l: &mut NonClonableType| do_something(l),
| - - ^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure `impl std::future::Future<Output = ()>` contains a lifetime `'2`
| let's call the lifetime of this reference `'1`
I'm lost to the point of having spent several hours reading to try to find inspiration and being unsure if what I'm trying is possible.