Rust provides infrastructure for benchmarking via the Bencher
struct and
the #[bench]
attribute. Details in the source code below.
// bench.rs
extern crate test;
use std::mem::replace;
use test::Bencher;
// bench: find the `BENCH_SIZE` first terms of the fibonacci sequence
static BENCH_SIZE: uint = 20;
// recursive fibonacci
fn fibonacci(n: uint) -> uint {
if n < 2 {
1
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}
// iterative fibonacci
struct Fibonacci {
curr: uint,
next: uint,
}
impl Iterator<uint> for Fibonacci {
fn next(&mut self) -> Option<uint> {
let new_next = self.curr + self.next;
let new_curr = replace(&mut self.next, new_next);
Some(replace(&mut self.curr, new_curr))
}
}
fn fibonacci_sequence() -> Fibonacci {
Fibonacci { curr: 1, next: 1 }
}
// function to benchmark must be annotated with `#[bench]`
#[bench]
fn recursive_fibonacci(b: &mut Bencher) {
// exact code to benchmark must be passed as a closure to the iter
// method of Bencher
b.iter(|| {
range(0, BENCH_SIZE).map(fibonacci).collect::<Vec<uint>>()
})
}
#[bench]
fn iterative_fibonacci(b: &mut Bencher) {
b.iter(|| {
fibonacci_sequence().take(BENCH_SIZE).collect::<Vec<uint>>()
})
}
The source needs to be compiled using the --test
flag, and the --bench
flag
must be passed to the resulting binary.
$ rustc --test -O bench.rs
$ ./bench --bench
running 2 tests
test iterative_fibonacci ... bench: 191 ns/iter (+/- 16)
test recursive_fibonacci ... bench: 49670 ns/iter (+/- 522)
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured