diff --git a/src/main.rs b/src/main.rs index 896267f..81a1b60 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,12 @@ use std::fmt::{self, Display}; use std::time::{Duration, Instant}; use termion::{color, style}; +#[derive(Debug, Clone)] +struct DurationDifference { + pub inner: Duration, + pub positive: bool, +} + #[derive(Debug, Clone)] struct BenchVec { pub inner: Vec, @@ -59,6 +65,23 @@ impl BenchVec { pub fn standard_deviation(&self) -> f64 { (self.sum().as_nanos() as f64 / (self.len() as f64 - 1f64)).sqrt() } + + /// Compares two benchmarks by calculating the average + pub fn compare(&self, other: Self) -> DurationDifference { + let avg1 = self.average(); + let avg2 = other.average(); + if avg1 > avg2 { + DurationDifference { + inner: avg1 - avg2, + positive: true, + } + } else { + DurationDifference { + inner: avg2 - avg1, + positive: false, + } + } + } } impl Display for BenchVec { @@ -67,39 +90,60 @@ impl Display for BenchVec { let standard_deviation = self.standard_deviation(); write!( f, - "Average Duration: {:?} (±{:.2}ns ~ {:.1}%)", + "Average Duration: {:?} (±{:.2}ns ~ {:.2}%)", avg_duration, standard_deviation, (standard_deviation / avg_duration.as_nanos() as f64) * 100f64 ) } } + +impl Display for DurationDifference { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}{:?}", + if self.positive { "+" } else { "-" }, + self.inner + ) + } +} + const BENCHMARK_ITERATIONS: usize = 1000; pub fn main() { - bench_function("Spawn and Stop thread", || { - to_test::start_stop_thread(); - }); - bench_function("MPSC channel 1000 u128", || { - to_test::send_mpsc_channel(); + bench_function("Spawn and Stop thread", || to_test::start_stop_thread()); + let mpsc = bench_function("MPSC channel 1000 u128", || to_test::send_mpsc_channel()); + let diff_channels = + bench_function("MPMC channel 1000 u128", || to_test::send_mpmc_channel()).compare(mpsc); + println!("Difference:\t {}", diff_channels); + bench_function("Multiply to 100", || to_test::multiply_to(100)); + let largest_single = bench_function("Largest prime until 10000000", || { + to_test::largest_prime(10000000) }); - bench_function("MPMC channel 1000 u128", || { - to_test::send_mpmc_channel(); - }); - bench_function("Multiply to 100", || { - to_test::multiply_to(100); - }); - bench_function("Largest prime until 10000000", || { - to_test::largest_prime(10000000); - }); - bench_function("Largest prime parallel until 10000000", || { - to_test::largest_prime_par(10000000); + let diff = bench_function("Largest prime parallel until 10000000", || { + to_test::largest_prime_par(10000000) }) + .compare(largest_single); + println!("Difference:\t {}", diff) +} + +/// Benchmarks a closure a given number of times and returns the +/// average duration as well as all measured durations +fn bench_n_times T>(n: usize, func: F) -> BenchVec { + let mut durations = BenchVec::new(); + for _ in 0..n { + let start = Instant::now(); + func(); + durations.push(start.elapsed()); + } + + durations } /// Benchmarks a closure a specific number of times /// and reports the results to the commandline -fn bench_function(name: &str, func: F) { +fn bench_function T>(name: &str, func: F) -> BenchVec { println!( "\n{}{}{}{}", color::Fg(color::LightBlue), @@ -114,19 +158,8 @@ fn bench_function(name: &str, func: F) { println!("Durations:\t {:?}", bench_durations.inner); } println!("{}", bench_durations); -} -/// Benchmarks a closure a given number of times and returns the -/// average duration as well as all measured durations -fn bench_n_times(n: usize, func: F) -> BenchVec { - let mut durations = BenchVec::new(); - for _ in 0..n { - let start = Instant::now(); - func(); - durations.push(start.elapsed()); - } - - durations + bench_durations } mod to_test {