Skip to content

Commit

Permalink
update example
Browse files Browse the repository at this point in the history
  • Loading branch information
PSeitz committed May 19, 2024
1 parent f1b529d commit 8d3d8f1
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 46 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ perf_event = ["perf-event"]
default = []

[[bench]]
name = "fibonacci_bench"
name = "bench"
harness = false

[[bench]]
Expand Down
28 changes: 28 additions & 0 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use binggan::{black_box, BenchRunner, PeakMemAlloc, INSTRUMENTED_SYSTEM};

#[global_allocator]
pub static GLOBAL: &PeakMemAlloc<std::alloc::System> = &INSTRUMENTED_SYSTEM;

pub fn factorial(mut n: usize) -> usize {
let mut result = 1usize;
while n > 0 {
result = result.wrapping_mul(black_box(n));
n -= 1;
}
result
}

fn bench_factorial() {
let mut runner = BenchRunner::new();
runner.set_alloc(GLOBAL); // Set the peak mem allocator. This will enable peak memory reporting.

for val in [100, 400] {
runner.bench_function(format!("factorial {}", val), move |_| {
factorial(black_box(val));
});
}
}

fn main() {
bench_factorial();
}
29 changes: 0 additions & 29 deletions benches/fibonacci_bench.rs

This file was deleted.

10 changes: 5 additions & 5 deletions src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ pub trait Bench<'a> {
fn get_input_name(&self) -> &str;
fn set_num_iter(&mut self, num_iter: usize);
/// Sample the number of iterations the benchmark should do
fn sample_num_iter(&self) -> usize;
fn sample_num_iter(&mut self) -> usize;
fn exec_bench(&mut self, alloc: &Option<Alloc>);
fn get_results(&mut self, group_name: Option<&str>) -> BenchResult;
fn clear_results(&mut self);
}

type CallBench<'a, I> = Box<dyn Fn(&'a I)>;
type CallBench<'a, I> = Box<dyn FnMut(&'a I)>;

pub(crate) struct NamedBench<'a, I> {
pub name: String,
Expand Down Expand Up @@ -83,7 +83,7 @@ impl<'a, I> Bench<'a> for InputWithBenchmark<'a, I> {
&self.input.name
}
#[inline]
fn sample_num_iter(&self) -> usize {
fn sample_num_iter(&mut self) -> usize {
self.bench.sample_and_get_iter(&self.input)
}
fn set_num_iter(&mut self, num_iter: usize) {
Expand Down Expand Up @@ -146,7 +146,7 @@ impl RunResult {
impl<'a, I> NamedBench<'a, I> {
#[inline]
/// Each group has its own number of iterations. This is not the final num_iter
pub fn sample_and_get_iter(&self, input: &NamedInput<'a, I>) -> usize {
pub fn sample_and_get_iter(&mut self, input: &NamedInput<'a, I>) -> usize {
// We want to run the benchmark for 100ms
const TARGET_MS_PER_BENCH: u64 = 100;
{
Expand Down Expand Up @@ -174,7 +174,7 @@ impl<'a, I> NamedBench<'a, I> {
}
#[inline]
pub fn exec_bench(
&self,
&mut self,
input: &NamedInput<'a, I>,
alloc: &Option<Alloc>,
profiler: &mut Option<PerfProfiler>,
Expand Down
21 changes: 10 additions & 11 deletions src/bench_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ impl BenchRunner {
/// Manully set the number of iterations each benchmark is called.
///
/// This disables the automatic detection of the number of iterations.
///
/// # Note
/// Use this to get more stable and comparable benchmark results, as the number of
/// iterations has a big impact on measurement and the iteration detection may
/// not always get the same num iterations between runs. There are ways implemented
/// to mitigate that but they are limited.
pub fn set_num_iter(&mut self, num_iter: usize) {
self.num_iter = Some(num_iter);
}
Expand Down Expand Up @@ -156,11 +162,11 @@ impl BenchRunner {
}

/// Run a single function
pub fn bench_function<F>(&mut self, name: String, f: F) -> &mut Self
pub fn bench_function<F, S: Into<String>>(&mut self, name: S, f: F) -> &mut Self
where
F: Fn(&()) + 'static,
{
let named_bench = NamedBench::new(name, Box::new(f));
let named_bench = NamedBench::new(name.into(), Box::new(f));
let bundle = InputWithBenchmark::new(
EMPTY_INPUT,
self.input_size_in_bytes,
Expand Down Expand Up @@ -213,19 +219,12 @@ impl BenchRunner {
// We report at the end, so the alignment is correct (could be calculated up front)
report_group(name, group, self.alloc.is_some());

//self.clear_results();
// TODO: clearing should be optional, to check the results yourself, e.g. in CI
for bench in group {
bench.clear_results();
}
}

// /// Clear the stored results of the benchmarks.
//pub fn clear_results(&mut self) {
//for bench in &mut self.benches {
//bench.clear_results();
//}
//}

fn run_sequential<'a>(benches: &mut [Box<dyn Bench<'a> + 'a>], alloc: &Option<Alloc>) {
for bench in benches {
for iteration in 0..NUM_RUNS {
Expand Down Expand Up @@ -301,7 +300,7 @@ impl BenchRunner {
// In order to make the benchmarks in a group comparable, it is imperative to call them
// the same numer of times
let (min_num_iter, max_num_iter) =
minmax(benches.iter().map(|b| b.sample_num_iter())).unwrap();
minmax(benches.iter_mut().map(|b| b.sample_num_iter())).unwrap();

if verbose {
println!(
Expand Down

0 comments on commit 8d3d8f1

Please sign in to comment.