2018-01-24 20:12:17 +01:00
|
|
|
use std::fmt;
|
|
|
|
|
|
2021-08-24 22:16:40 +02:00
|
|
|
use crate::benchmark::MIN_EXECUTION_TIME;
|
2026-10-05 11:46:49 +02:00
|
|
|
use crate::quantity::{FormatQuantity, Time, TimeUnit};
|
2018-01-24 20:12:17 +01:00
|
|
|
|
2022-11-20 21:18:03 +01:00
|
|
|
pub struct OutlierWarningOptions {
|
|
|
|
|
pub warmup_in_use: bool,
|
|
|
|
|
pub prepare_in_use: bool,
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-24 20:12:17 +01:00
|
|
|
/// A list of all possible warnings
|
|
|
|
|
pub enum Warnings {
|
|
|
|
|
FastExecutionTime,
|
|
|
|
|
NonZeroExitCode,
|
2026-10-05 10:32:32 +02:00
|
|
|
SlowInitialRun(Time, OutlierWarningOptions),
|
2022-11-20 21:18:03 +01:00
|
|
|
OutliersDetected(OutlierWarningOptions),
|
2018-01-24 20:12:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for Warnings {
|
2019-05-07 11:55:38 +02:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-01-24 20:12:17 +01:00
|
|
|
match *self {
|
|
|
|
|
Warnings::FastExecutionTime => write!(
|
|
|
|
|
f,
|
2026-10-05 11:46:49 +02:00
|
|
|
"Command took less than {} ms to complete. Note that the results might be \
|
2022-03-05 12:47:26 +01:00
|
|
|
inaccurate because hyperfine can not calibrate the shell startup time much \
|
|
|
|
|
more precise than this limit. You can try to use the `-N`/`--shell=none` \
|
|
|
|
|
option to disable the shell completely.",
|
2026-10-05 11:46:49 +02:00
|
|
|
MIN_EXECUTION_TIME.format_with_precision(TimeUnit::MilliSecond, 0)
|
2018-01-24 20:12:17 +01:00
|
|
|
),
|
|
|
|
|
Warnings::NonZeroExitCode => write!(f, "Ignoring non-zero exit code."),
|
2022-11-20 21:18:03 +01:00
|
|
|
Warnings::SlowInitialRun(time_first_run, ref options) => write!(
|
2018-01-24 20:12:17 +01:00
|
|
|
f,
|
|
|
|
|
"The first benchmarking run for this command was significantly slower than the \
|
2022-11-20 21:18:03 +01:00
|
|
|
rest ({time}). This could be caused by (filesystem) caches that were not filled until \
|
|
|
|
|
after the first run. {hints}",
|
2026-10-05 11:46:49 +02:00
|
|
|
time=time_first_run.format_auto(),
|
2022-11-20 21:18:03 +01:00
|
|
|
hints=match (options.warmup_in_use, options.prepare_in_use) {
|
|
|
|
|
(true, true) => "You are already using both the '--warmup' option as well \
|
|
|
|
|
as the '--prepare' option. Consider re-running the benchmark on a quiet system. \
|
|
|
|
|
Maybe it was a random outlier. Alternatively, consider increasing the warmup \
|
|
|
|
|
count.",
|
|
|
|
|
(true, false) => "You are already using the '--warmup' option which helps \
|
|
|
|
|
to fill these caches before the actual benchmark. You can either try to \
|
|
|
|
|
increase the warmup count further or re-run this benchmark on a quiet system \
|
|
|
|
|
in case it was a random outlier. Alternatively, consider using the '--prepare' \
|
|
|
|
|
option to clear the caches before each timing run.",
|
|
|
|
|
(false, true) => "You are already using the '--prepare' option which can \
|
|
|
|
|
be used to clear caches. If you did not use a cache-clearing command with \
|
|
|
|
|
'--prepare', you can either try that or consider using the '--warmup' option \
|
|
|
|
|
to fill those caches before the actual benchmark.",
|
|
|
|
|
(false, false) => "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."
|
|
|
|
|
}
|
2018-01-24 20:12:17 +01:00
|
|
|
),
|
2022-11-20 21:18:03 +01:00
|
|
|
Warnings::OutliersDetected(ref options) => write!(
|
2018-01-24 20:12:17 +01:00
|
|
|
f,
|
|
|
|
|
"Statistical outliers were detected. Consider re-running this benchmark on a quiet \
|
2022-11-20 21:18:03 +01:00
|
|
|
system without any interferences from other programs.{hint}",
|
|
|
|
|
hint=if options.warmup_in_use && options.prepare_in_use {
|
|
|
|
|
""
|
|
|
|
|
} else {
|
|
|
|
|
" It might help to use the '--warmup' or '--prepare' options."
|
|
|
|
|
}
|
2018-01-24 20:12:17 +01:00
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|