diff --git a/src/hyperfine/benchmark.rs b/src/hyperfine/benchmark.rs index fca2920..5cac7f4 100644 --- a/src/hyperfine/benchmark.rs +++ b/src/hyperfine/benchmark.rs @@ -2,10 +2,11 @@ use std::io; use std::process::{Command, Stdio}; use std::time::Instant; -use ansi_term::Colour::{Cyan, Green, White, Yellow}; +use ansi_term::Colour::{Cyan, Green, White, Yellow, Purple}; use statistical::{mean, standard_deviation}; -use hyperfine::internal::{get_progress_bar, HyperfineOptions, Second, Warnings, MIN_EXECUTION_TIME}; +use hyperfine::internal::{get_progress_bar, max, min, HyperfineOptions, Second, Warnings, + MIN_EXECUTION_TIME}; use hyperfine::format::{format_duration, format_duration_unit, Unit}; /// Results from timing a single shell command @@ -172,17 +173,28 @@ pub fn run_benchmark( bar.finish_and_clear(); // Compute statistical quantities - - // Corrected execution times - let mean = mean(&execution_times); - let stddev = standard_deviation(&execution_times, Some(mean)); + let t_mean = mean(&execution_times); + let t_stddev = standard_deviation(&execution_times, Some(t_mean)); + let t_min = min(&execution_times); + let t_max = max(&execution_times); // Formatting and console output - let (mean_str, unit_mean) = format_duration_unit(mean, Unit::Auto); - let stddev_str = format_duration(stddev, unit_mean); - let time_fmt = format!("{} ± {}", mean_str, stddev_str); + let (mean_str, unit_mean) = format_duration_unit(t_mean, Unit::Auto); + let stddev_str = format_duration(t_stddev, unit_mean); + let min_str = format_duration(t_min, unit_mean); + let max_str = format_duration(t_max, unit_mean); - println!(" Time: {}", Green.paint(time_fmt)); + let mean_stddev = format!("{} ± {}", Green.bold().paint(mean_str), Green.paint(stddev_str)); + println!( + " Time: {:<40} mean ± stddev", + mean_stddev + ); + + let min_max = format!("{} … {}", Purple.paint(min_str), Purple.paint(max_str)); + println!( + " Range: {:<38} min … max", + min_max + ); // Warnings let mut warnings = vec![]; diff --git a/src/hyperfine/format.rs b/src/hyperfine/format.rs index b9c6a74..901414a 100644 --- a/src/hyperfine/format.rs +++ b/src/hyperfine/format.rs @@ -1,6 +1,6 @@ use hyperfine::internal::Second; -#[derive(PartialEq)] +#[derive(Clone, Copy, PartialEq)] pub enum Unit { Auto, Second, @@ -15,8 +15,8 @@ pub fn format_duration(duration: Second, unit: Unit) -> String { pub fn format_duration_unit(duration: Second, unit: Unit) -> (String, Unit) { if (duration < 1.0 && unit == Unit::Auto) || unit == Unit::MilliSecond { - (format!("{:.1} ms", duration * 1e3), Unit::MilliSecond) + (format!("{:5.1} ms", duration * 1e3), Unit::MilliSecond) } else { - (format!("{:.3} s", duration), Unit::Second) + (format!("{:5.3} s", duration), Unit::Second) } } diff --git a/src/hyperfine/internal.rs b/src/hyperfine/internal.rs index 07ac952..c592e20 100644 --- a/src/hyperfine/internal.rs +++ b/src/hyperfine/internal.rs @@ -66,3 +66,19 @@ impl fmt::Display for Warnings { } } } + +/// A max function for f64's without NaNs +pub fn max(vals: &[f64]) -> f64 { + vals.iter() + .max_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() + .clone() +} + +/// A min function for f64's without NaNs +pub fn min(vals: &[f64]) -> f64 { + vals.iter() + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() + .clone() +}