diff --git a/Cargo.lock b/Cargo.lock index baabc5c..752cd5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -53,7 +53,15 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "colored" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -68,7 +76,7 @@ dependencies = [ "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -89,9 +97,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "hyperfine" version = "0.3.0" dependencies = [ - "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)", + "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "statistical 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -150,7 +158,7 @@ dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -159,7 +167,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -169,7 +177,7 @@ name = "num-complex" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -178,7 +186,7 @@ name = "num-integer" version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -187,7 +195,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -197,13 +205,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -231,7 +239,7 @@ dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -378,11 +386,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -392,12 +400,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-i686-pc-windows-gnu" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-x86_64-pc-windows-gnu" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] @@ -408,6 +416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6" "checksum clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f84dec9bc083ce2503908cd305af98bd363da6f54bf8d4bf0ac14ee749ad5d1" +"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7649ca90478264b9686aac8d269fcb014f14c2bed7c79a7e51b9f6afd4d783eb" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" @@ -423,7 +432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" -"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" +"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" "checksum parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f35048d735bb93dd115a0030498785971aab3234d311fbe273d020084d26bd8" @@ -447,7 +456,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b09fb3b6f248ea4cd42c9a65113a847d612e17505d6ebd1f7357ad68a8bf8693" +"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc" -"checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index b06ddcf..ef8cd7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/sharkdp/hyperfine" version = "0.3.0" [dependencies] -ansi_term = "0.10" +colored = "1.6" indicatif = "0.9" statistical = "0.1" libc = "0.2" diff --git a/src/hyperfine/benchmark.rs b/src/hyperfine/benchmark.rs index 4923a43..f98198c 100644 --- a/src/hyperfine/benchmark.rs +++ b/src/hyperfine/benchmark.rs @@ -2,11 +2,12 @@ use std::io; use std::process::{Command, Stdio}; use std::time::Instant; -use ansi_term::Colour::{Blue, Cyan, Green, Purple, White, Yellow}; +use colored::*; use statistical::{mean, standard_deviation}; use hyperfine::internal::{get_progress_bar, max, min, CmdFailureAction, HyperfineOptions, Second, - Warnings, MIN_EXECUTION_TIME}; + MIN_EXECUTION_TIME}; +use hyperfine::warnings::Warnings; use hyperfine::format::{format_duration, format_duration_unit}; use hyperfine::cputime::{cpu_time_interval, get_cpu_times}; use hyperfine::outlier_detection::{modified_zscores, OUTLIER_THRESHOLD}; @@ -148,8 +149,8 @@ pub fn run_benchmark( ) -> io::Result<()> { println!( "{}{}: {}", - White.bold().paint("Benchmark #"), - White.bold().paint((num + 1).to_string()), + "Benchmark #".bold(), + (num + 1).to_string().bold(), cmd ); println!(); @@ -208,7 +209,7 @@ pub fn run_benchmark( let msg = { let mean = format_duration(mean(×_real), None); - format!("Current estimate: {}", Green.paint(mean)) + format!("Current estimate: {}", mean.to_string().green()) }; progress_bar.set_message(&msg); @@ -244,22 +245,22 @@ pub fn run_benchmark( let system_str = format_duration(system_mean, Some(user_unit)); println!( - " Time ({} ± {}): {} ± {} [User: {}, System: {}]", - Green.bold().paint("mean"), - Green.paint("σ"), - Green.bold().paint(mean_str), - Green.paint(stddev_str), - Blue.paint(user_str), - Blue.paint(system_str) + " Time ({} ± {}): {:>8} ± {:>8} [User: {}, System: {}]", + "mean".green().bold(), + "σ".green(), + mean_str.green().bold(), + stddev_str.green(), + user_str.blue(), + system_str.blue() ); println!(" "); println!( - " Range ({} … {}): {} … {}", - Cyan.paint("min"), - Purple.paint("max"), - Cyan.paint(min_str), - Purple.paint(max_str) + " Range ({} … {}): {:>8} … {:>8}", + "min".cyan(), + "max".purple(), + min_str.cyan(), + max_str.purple() ); // Warnings @@ -278,7 +279,7 @@ pub fn run_benchmark( // Run outlier detection let scores = modified_zscores(×_real); if scores[0] > OUTLIER_THRESHOLD { - warnings.push(Warnings::SlowInitialRun); + warnings.push(Warnings::SlowInitialRun(times_real[0])); } else if scores.iter().any(|&s| s > OUTLIER_THRESHOLD) { warnings.push(Warnings::OutliersDetected); } @@ -286,7 +287,7 @@ pub fn run_benchmark( if !warnings.is_empty() { eprintln!(" "); for warning in &warnings { - eprintln!(" {}: {}", Yellow.paint("Warning"), warning); + eprintln!(" {}: {}", "Warning".yellow(), warning); } } diff --git a/src/hyperfine/format.rs b/src/hyperfine/format.rs index 0ab88c8..cba415c 100644 --- a/src/hyperfine/format.rs +++ b/src/hyperfine/format.rs @@ -17,9 +17,9 @@ pub fn format_duration(duration: Second, unit: Option) -> String { /// Like `format_duration`, but returns the target unit as well. pub fn format_duration_unit(duration: Second, unit: Option) -> (String, Unit) { if (duration < 1.0 && unit.is_none()) || unit == Some(Unit::MilliSecond) { - (format!("{:5.1} ms", duration * 1e3), Unit::MilliSecond) + (format!("{:.1} ms", duration * 1e3), Unit::MilliSecond) } else { - (format!("{:6.3} s", duration), Unit::Second) + (format!("{:.3} s", duration), Unit::Second) } } @@ -27,12 +27,12 @@ pub fn format_duration_unit(duration: Second, unit: Option) -> (String, Un fn test_format_duration_unit_basic() { let (out_str, out_unit) = format_duration_unit(1.3, None); - assert_eq!(" 1.300 s", out_str); + assert_eq!("1.300 s", out_str); assert_eq!(Unit::Second, out_unit); let (out_str, out_unit) = format_duration_unit(1.0, None); - assert_eq!(" 1.000 s", out_str); + assert_eq!("1.000 s", out_str); assert_eq!(Unit::Second, out_unit); let (out_str, out_unit) = format_duration_unit(0.999, None); @@ -42,7 +42,7 @@ fn test_format_duration_unit_basic() { let (out_str, out_unit) = format_duration_unit(0.0, None); - assert_eq!(" 0.0 ms", out_str); + assert_eq!("0.0 ms", out_str); assert_eq!(Unit::MilliSecond, out_unit); let (out_str, out_unit) = format_duration_unit(1000.0, None); @@ -55,7 +55,7 @@ fn test_format_duration_unit_basic() { fn test_format_duration_unit_with_unit() { let (out_str, out_unit) = format_duration_unit(1.3, Some(Unit::Second)); - assert_eq!(" 1.300 s", out_str); + assert_eq!("1.300 s", out_str); assert_eq!(Unit::Second, out_unit); let (out_str, out_unit) = format_duration_unit(1.3, Some(Unit::MilliSecond)); diff --git a/src/hyperfine/internal.rs b/src/hyperfine/internal.rs index 0ddb488..1b1507c 100644 --- a/src/hyperfine/internal.rs +++ b/src/hyperfine/internal.rs @@ -1,5 +1,3 @@ -use std::fmt; - use indicatif::{ProgressBar, ProgressStyle}; /// Type alias for unit of time @@ -62,41 +60,6 @@ pub fn get_progress_bar(length: u64, msg: &str) -> ProgressBar { progress_bar } -/// Possible benchmark warnings -pub enum Warnings { - FastExecutionTime, - NonZeroExitCode, - SlowInitialRun, - OutliersDetected, -} - -impl fmt::Display for Warnings { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Warnings::FastExecutionTime => write!( - f, - "Command took less than {:.0} ms to complete. Results might be inaccurate.", - MIN_EXECUTION_TIME * 1e3 - ), - Warnings::NonZeroExitCode => write!(f, "Ignoring non-zero exit code."), - Warnings::SlowInitialRun => write!( - f, - "The first benchmarking run for this command was significantly slower than the \ - rest. This could be caused by (filesystem) caches that were not filled. You \ - should consider using the '--warmup' option to fill those caches before the \ - benchmark. Alternatively, use the '--prepare' option to clear the caches before \ - each timing run." - ), - Warnings::OutliersDetected => write!( - f, - "Statistical outliers were detected. Consider re-running this benchmark without \ - any interferences from other programs. It might help to use the '--warmup' or \ - '--prepare' options to mitigate outliers." - ), - } - } -} - /// A max function for f64's without NaNs pub fn max(vals: &[f64]) -> f64 { *vals.iter() diff --git a/src/hyperfine/mod.rs b/src/hyperfine/mod.rs index 4fa47b5..9e74d4d 100644 --- a/src/hyperfine/mod.rs +++ b/src/hyperfine/mod.rs @@ -3,3 +3,4 @@ pub mod format; pub mod internal; pub mod cputime; pub mod outlier_detection; +pub mod warnings; diff --git a/src/hyperfine/warnings.rs b/src/hyperfine/warnings.rs new file mode 100644 index 0000000..4e21f26 --- /dev/null +++ b/src/hyperfine/warnings.rs @@ -0,0 +1,40 @@ +use std::fmt; + +use hyperfine::internal::{Second, MIN_EXECUTION_TIME}; +use hyperfine::format::format_duration; + +/// A list of all possible warnings +pub enum Warnings { + FastExecutionTime, + NonZeroExitCode, + SlowInitialRun(Second), + OutliersDetected, +} + +impl fmt::Display for Warnings { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Warnings::FastExecutionTime => write!( + f, + "Command took less than {:.0} ms to complete. Results might be inaccurate.", + MIN_EXECUTION_TIME * 1e3 + ), + Warnings::NonZeroExitCode => write!(f, "Ignoring non-zero exit code."), + Warnings::SlowInitialRun(t_first) => write!( + f, + "The first benchmarking run for this command was significantly slower than the \ + rest ({}). This could be caused by (filesystem) caches that were not filled until \ + after the first run. You should consider using the '--warmup' option to fill \ + those caches before the actual benchmark. Alternatively, use the '--prepare' \ + option to clear the caches before each timing run.", + format_duration(t_first, None) + ), + Warnings::OutliersDetected => write!( + f, + "Statistical outliers were detected. Consider re-running this benchmark on a quiet \ + PC without any interferences from other programs. It might help to use the \ + '--warmup' or '--prepare' options." + ), + } + } +} diff --git a/src/main.rs b/src/main.rs index 3b3306b..0d9bd3d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -extern crate ansi_term; #[macro_use] extern crate clap; +extern crate colored; extern crate indicatif; extern crate libc; extern crate statistical; @@ -13,7 +13,7 @@ use std::cmp; use std::error::Error; use std::io; -use ansi_term::Colour::Red; +use colored::*; use clap::{App, AppSettings, Arg}; mod hyperfine; @@ -23,7 +23,7 @@ use hyperfine::benchmark::{mean_shell_spawning_time, run_benchmark}; /// Print error message to stderr and terminate pub fn error(message: &str) -> ! { - eprintln!("{}: {}", Red.paint("Error"), message); + eprintln!("{} {}", "Error:".red(), message); std::process::exit(1); }