Benchmarking
Cargo has built-in benchmarking, but using it requires the nightly unstable code channel. I generally don't recommend relying on nightly code! If you are writing performance-critical code, benchmarking is essential. Fortunately, Rust makes it relatively straightforward to include benchmarks with a bit of boilerplate.
Quick and Dirty Benchmarks
This example is in
project/simple_bench
A quick and dirty way to benchmark operations is to use Instant
and Duration
:
use std::time::Instant; fn main() { let now = Instant::now(); let mut i = 0; for j in 0 .. 1_000 { i += j*j; } let elapsed = now.elapsed(); println!("Time elapsed: {} nanos", elapsed.as_nanos()); println!("{i}"); }
Criterion
This project is in
projects/part2/criterion_bench
In Cargo.toml
, add:
[dev-dependencies]
criterion = { version = "0.4", features = [ "html_reports" ] }
[[bench]]
name = "my_benchmark"
harness = false
[dev-dependencies]
is new! This is a dependency that is only loaded by development tools, and isn't integrated into your final program. No space is wasted.
Create <project>/benches/my_benchmark.rs
:
#![allow(unused)] fn main() { use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn fibonacci(n: u64) -> u64 { match n { 0 => 1, 1 => 1, n => fibonacci(n-1) + fibonacci(n-2), } } fn criterion_benchmark(c: &mut Criterion) { c.bench_function("fib 20", |b| b.iter(|| fibonacci(black_box(20)))); } criterion_group!(benches, criterion_benchmark); criterion_main!(benches); }
Run cargo bench
and see the result.
Go to target/criterion
and you have a full HTML report with statistics.
Flamegraphs
It pretty much requires Linux (and the perf
infrastructure), but it's worth looking at Cargo Flamegraphs if you are developing on that platform. It's an easy wrapper around perf
for generating flamegraphs to find your hotspots.