I'm running these benchmarks, they use a function which is a loop that counts to 10M and 100M:
use crab::count_up_to;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::Rng;
pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("10M", |b| {
b.iter(|| {
let num = rand::thread_rng().gen_range(0..100);
let r = count_up_to(black_box(10_000_000 + num));
eprintln!("{}", r);
});
});
c.bench_function("100M", |b| {
b.iter(|| {
let r = count_up_to(100_000_000);
eprintln!("{}", black_box(r));
});
});
c.bench_function("hello", |b| {
b.iter(|| {
eprintln!("{}", "hello");
});
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
I've added a third benchmark that only outputs to stderr for reference. The problem as you may guess is that all 3 benchmarks take the same time, less than 1µs, which clearly mean the count_up_to function is being optimized out.
I wonder why that is since I end up using the result of the function and as you may note in the first test (the 10M) the parameters are not always the same since a little random noise is added. I've also tried to use black_box in different places with no luck.
Any help is greatly appreciated.
Here's Cargo.toml and the implementation of count_up_to:
[package]
name = "crab"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dev-dependencies]
criterion = { version = "0.4", features = ["html_reports"] }
rand = "0.8"
[[bench]]
name = "count"
harness = false
pub fn count_up_to(n: usize) -> usize {
let mut count = 0;
while count < n {
count += 1;
}
count / 2 * 100
}
The compiler just realizes the loop is equal to
let count = n: https://rust.godbolt.org/z/Mo1hGa5Pa. You can addblack_box():count += std::hint::black_box(1);.Also, printing in
iter()is a very bad idea, it'll take up all of the time. And you'll need toblack_box()the100_000_000parameter too.