[github](https://github.com/OTheDev/benchplot) [![Multi-Platform Test](https://github.com/OTheDev/benchplot/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/OTheDev/benchplot/actions/workflows/test.yml) [![Static Analysis](https://github.com/OTheDev/benchplot/actions/workflows/static.yml/badge.svg?branch=main)](https://github.com/OTheDev/benchplot/actions/workflows/static.yml) # benchplot `benchplot` is a utility for benchmarking functions over various input sizes and plotting the results. ## Usage

```rust use benchplot::{BenchBuilder, BenchFnArg, BenchFnNamed}; use rand::Rng; fn main() { // Functions to benchmark (with names) let functions: Vec, Vec>> = vec![ (Box::new(bubble_sort), "Bubble Sort"), (Box::new(insertion_sort), "Insertion Sort"), (Box::new(merge_sort), "Merge Sort"), ]; // For each size, returns an argument to pass to the functions to benchmark let argfunc: BenchFnArg> = Box::new(|size: usize| { let mut rng = rand::thread_rng(); (0..size).map(|_| rng.gen_range(1..=1000)).collect() }); // Input sizes to test. NOTE: a wider range was used for the image above. let sizes: Vec = (0..15).map(|k| 1 << k).collect(); // Build a `Bench` instance let mut bench = BenchBuilder::new(functions, argfunc, sizes) .repetitions(1) .parallel(true) .assert_equal(true) .build() .unwrap(); // Run benchmarks and plot them bench .run() .plot("output.svg") .title("Sorting Algorithms") .build() .expect("Plotting failed"); } // Bubble Sort: O(n²) fn bubble_sort(mut a: Vec) -> Vec { let mut n = a.len(); while n > 1 { let mut np = 0; for i in 1..n { if a[i - 1] > a[i] { a.swap(i - 1, i); np = i; } } n = np; } a } // Insertion Sort: O(n²) fn insertion_sort(mut a: Vec) -> Vec { let n = a.len(); for i in 1..n { let x = a[i]; let mut j = i; while j > 0 && a[j - 1] > x { a[j] = a[j - 1]; j -= 1; } a[j] = x; } a } // Merge Sort: O(n log n) // Based on code from https://en.wikipedia.org/wiki/Merge_sort fn merge_sort(mut a: Vec) -> Vec { let len = a.len(); let mut b = a.clone(); top_down_split_merge(&mut a, 0, len, &mut b); a } fn top_down_split_merge( b: &mut [i32], begin: usize, end: usize, a: &mut [i32], ) { if end - begin <= 1 { return; } let middle = (end + begin) / 2; top_down_split_merge(a, begin, middle, b); top_down_split_merge(a, middle, end, b); top_down_merge(b, begin, middle, end, a); } fn top_down_merge( b: &mut [i32], begin: usize, middle: usize, end: usize, a: &mut [i32], ) { let mut i = begin; let mut j = middle; for b_k in b.iter_mut().take(end).skip(begin) { if i < middle && (j >= end || a[i] <= a[j]) { *b_k = a[i]; i += 1; } else { *b_k = a[j]; j += 1; } } } ``` ## License This project is dual-licensed under either the [Apache License, Version 2.0](https://github.com/OTheDev/benchplot/blob/main/LICENSE-APACHE) or the [MIT License](https://github.com/OTheDev/benchplot/blob/main/LICENSE-MIT), at your option. ## Contributing Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you shall be dual-licensed as above, without any additional terms or conditions.