Update warnings, switch to colored crate

This commit is contained in:
sharkdp 2018-01-24 20:12:17 +01:00 committed by David Peter
parent 2ddc21c7d4
commit d5c21ec272
8 changed files with 101 additions and 87 deletions

51
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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(&times_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(&times_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);
}
}

View File

@ -17,9 +17,9 @@ pub fn format_duration(duration: Second, unit: Option<Unit>) -> String {
/// Like `format_duration`, but returns the target unit as well.
pub fn format_duration_unit(duration: Second, unit: Option<Unit>) -> (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<Unit>) -> (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));

View File

@ -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()

View File

@ -3,3 +3,4 @@ pub mod format;
pub mod internal;
pub mod cputime;
pub mod outlier_detection;
pub mod warnings;

40
src/hyperfine/warnings.rs Normal file
View File

@ -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."
),
}
}
}

View File

@ -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);
}