Change bench function to accept any return type

master
Trivernis 5 years ago
parent 5e0089aedb
commit 04cfc2cb1f

@ -8,6 +8,12 @@ use std::fmt::{self, Display};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use termion::{color, style}; use termion::{color, style};
#[derive(Debug, Clone)]
struct DurationDifference {
pub inner: Duration,
pub positive: bool,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct BenchVec { struct BenchVec {
pub inner: Vec<Duration>, pub inner: Vec<Duration>,
@ -59,6 +65,23 @@ impl BenchVec {
pub fn standard_deviation(&self) -> f64 { pub fn standard_deviation(&self) -> f64 {
(self.sum().as_nanos() as f64 / (self.len() as f64 - 1f64)).sqrt() (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 { impl Display for BenchVec {
@ -67,39 +90,60 @@ impl Display for BenchVec {
let standard_deviation = self.standard_deviation(); let standard_deviation = self.standard_deviation();
write!( write!(
f, f,
"Average Duration: {:?} (±{:.2}ns ~ {:.1}%)", "Average Duration: {:?} (±{:.2}ns ~ {:.2}%)",
avg_duration, avg_duration,
standard_deviation, standard_deviation,
(standard_deviation / avg_duration.as_nanos() as f64) * 100f64 (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; const BENCHMARK_ITERATIONS: usize = 1000;
pub fn main() { pub fn main() {
bench_function("Spawn and Stop thread", || { bench_function("Spawn and Stop thread", || to_test::start_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("MPSC channel 1000 u128", || { let diff = bench_function("Largest prime parallel until 10000000", || {
to_test::send_mpsc_channel(); to_test::largest_prime_par(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);
}) })
.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, F: Fn() -> 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 /// Benchmarks a closure a specific number of times
/// and reports the results to the commandline /// and reports the results to the commandline
fn bench_function<F: Fn()>(name: &str, func: F) { fn bench_function<T, F: Fn() -> T>(name: &str, func: F) -> BenchVec {
println!( println!(
"\n{}{}{}{}", "\n{}{}{}{}",
color::Fg(color::LightBlue), color::Fg(color::LightBlue),
@ -114,19 +158,8 @@ fn bench_function<F: Fn()>(name: &str, func: F) {
println!("Durations:\t {:?}", bench_durations.inner); println!("Durations:\t {:?}", bench_durations.inner);
} }
println!("{}", bench_durations); println!("{}", bench_durations);
}
/// Benchmarks a closure a given number of times and returns the bench_durations
/// average duration as well as all measured durations
fn bench_n_times<F: Fn()>(n: usize, func: F) -> BenchVec {
let mut durations = BenchVec::new();
for _ in 0..n {
let start = Instant::now();
func();
durations.push(start.elapsed());
}
durations
} }
mod to_test { mod to_test {

Loading…
Cancel
Save