24.9 Benchmarking
Performance is crucial in systems programming. Rust offers multiple ways to measure runtime efficiency:
- Nightly-only Benchmark Harness: A built-in harness requiring the nightly compiler.
criterion
anddivan
Crates: Third-party benchmarking libraries with statistical analysis and stable Rust support.
Below are concise examples for each method.
24.9.1 The Built-in Benchmark Harness (Nightly Only)
If you use nightly Rust, you can use the language's built-in benchmarking support. For example:
#![feature(test)]
extern crate test;
pub fn add_two(a: i32) -> i32 {
a + 2
}
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[test]
fn it_works() {
assert_eq!(add_two(2), 4);
}
#[bench]
fn bench_add_two(b: &mut Bencher) {
b.iter(|| add_two(2));
}
}
- Add
#![feature(test)]
at the top (an unstable feature). - Import the
test
crate. - Mark benchmark functions with
#[bench]
, taking a&mut Bencher
parameter. - Use
b.iter(...)
to specify the code to measure.
To run tests and benchmarks:
cargo test
cargo bench
Note: Compiler optimizations might remove what it sees as “unused” code. To prevent this, consider using
test::black_box(...)
around critical operations.
24.9.2 criterion
Criterion is a popular benchmarking crate for stable Rust. It provides advanced features, such as statistical measurements and detailed reports.
Quickstart
-
Add
criterion
todev-dependencies
inCargo.toml
:[dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } [[bench]] name = "my_benchmark" harness = false
-
Create
benches/my_benchmark.rs
:use std::hint::black_box; use criterion::{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
Criterion generates a report (often in target/criterion/report/index.html
) that includes detailed results and plots.
24.9.3 divan
Divan is a newer benchmarking crate (currently around version 0.1.17
) requiring Rust 1.80.0 or later.
Getting Started
-
In
Cargo.toml
:[dev-dependencies] divan = "0.1.17" [[bench]] name = "example" harness = false
-
Create
benches/example.rs
:fn main() { // Execute registered benchmarks. divan::main(); } // Register the `fibonacci` function and benchmark it with multiple arguments. #[divan::bench(args = [1, 2, 4, 8, 16, 32])] fn fibonacci(n: u64) -> u64 { if n <= 1 { 1 } else { fibonacci(n - 2) + fibonacci(n - 1) } }
-
Run:
cargo bench
Divan outputs benchmark results on the command line; consult the Divan documentation for more features.