I am running benchmarks with Criterion but am facing issues with functions that have an input that does not implement the Copy trait.
For example, I have set up the following benchmark for a function with the signature pub fn hash(vector: Vec<&str>) -> u64
.
pub fn criterion_benchmark(c: &mut Criterion) {
let s: String = String::from("Hello World!");
let tokens: Vec<&str> = hashing::tokenize(&s);
c.bench_function(
"hash",
|b| b.iter(|| {
hashing::hash(tokens)
}),
);
}
However, unlike with types that have the Copy trait, the compiler throws out the following ownership error.
error[E0507]: cannot move out of `tokens`, a captured variable in an `FnMut` closure
--> benches/benchmark.rs:17:34
|
13 | let tokens: Vec<&str> = hashing::tokenize(&s);
| ------ captured outer variable
...
17 | hashing::hash(tokens)
| ^^^^^^ move occurs because `tokens` has type `Vec<&str>`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `tokens`, a captured variable in an `FnMut` closure
--> benches/benchmark.rs:16:20
|
13 | let tokens: Vec<&str> = hashing::tokenize(&s);
| ------ captured outer variable
...
16 | |b| b.iter(|| {
| ^^ move out of `tokens` occurs here
17 | hashing::hash(tokens)
| ------
| |
| move occurs because `tokens` has type `Vec<&str>`, which does not implement the `Copy` trait
| move occurs due to use in closure
How can non-copyable inputs be passed to the benchmarked function without running into ownership issues?
As suggested by @Stargateur, cloning the parameter solved the ownership issue.
pub fn criterion_benchmark(c: &mut Criterion) {
let s: String = String::from("Hello World!");
let tokens: Vec<&str> = hashing::tokenize(&s);
c.bench_function(
"hash",
|b| b.iter(|| {
hashing::hash(tokens.clone())
}),
);
}
However, as proposed by @DenysSéguret and @Masklinn, changing the hash
function to accept &[&str]
avoids the ~50% overhead of cloning the vector.