mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-10-30 00:38:56 +00:00
Extend the --runs=N option added in d78c33b (Added options to specify
the max/exact numbers of runs., 2018-09-09) to support --runs=1
instead of dying with a usage error.
This is useful to do ad-hoc testing of your commands while they might
still have syntax errors, or just for doing one run where you don't
care about the stddev.
Before:
$ /usr/bin/hyperfine -s basic -r 1 -L n 5,10 'sleep 0.{n}'
Error: Number of runs below two
After (-s basic) also works:
$ hyperfine -r 1 -L n 5,10 'sleep 0.{n}'
Benchmark 1: sleep 0.5
Time (abs ≡): 500.6 ms [User: 0.6 ms, System: 0.0 ms]
Benchmark 2: sleep 0.10
Time (abs ≡): 100.8 ms [User: 0.7 ms, System: 0.0 ms]
Summary
'sleep 0.10' ran
4.97 ± 0.00 times faster than 'sleep 0.5'
This likewise combines correctly with -m and -M, probably not very
useful, but if you're tweaking an existing command-line:
$ hyperfine -m 1 -M 1 -L n 5,10 'sleep 0.{n}'
Benchmark 1: sleep 0.5
Time (abs ≡): 500.6 ms [User: 0.5 ms, System: 0.0 ms]
Benchmark 2: sleep 0.10
Time (abs ≡): 100.6 ms [User: 0.6 ms, System: 0.0 ms]
Summary
'sleep 0.10' ran
4.98 ± 0.00 times faster than 'sleep 0.5'
The "± 0.00" output in "faster than" should probably be adjusted too,
or we could keep it for consistency. I didn't implement that because
this is the first time I do anything in Rust, and I ran out of
template to copy when wanting to quickly implement this in
write_benchmark_comparison() in main.rs.
97 lines
3.3 KiB
Rust
97 lines
3.3 KiB
Rust
use std::error::Error;
|
|
use std::fmt;
|
|
use std::num;
|
|
use std::num::ParseIntError;
|
|
|
|
use rust_decimal::Error as DecimalError;
|
|
|
|
#[derive(Debug)]
|
|
pub enum ParameterScanError {
|
|
ParseIntError(num::ParseIntError),
|
|
ParseDecimalError(DecimalError),
|
|
EmptyRange,
|
|
TooLarge,
|
|
ZeroStep,
|
|
StepRequired,
|
|
UnexpectedCommandNameCount(usize, usize),
|
|
}
|
|
|
|
impl From<num::ParseIntError> for ParameterScanError {
|
|
fn from(e: num::ParseIntError) -> ParameterScanError {
|
|
ParameterScanError::ParseIntError(e)
|
|
}
|
|
}
|
|
|
|
impl From<DecimalError> for ParameterScanError {
|
|
fn from(e: DecimalError) -> ParameterScanError {
|
|
ParameterScanError::ParseDecimalError(e)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ParameterScanError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match *self {
|
|
ParameterScanError::ParseIntError(ref e) => write!(f, "{}", e),
|
|
ParameterScanError::ParseDecimalError(ref e) => write!(f, "{}", e),
|
|
ParameterScanError::EmptyRange => write!(f, "Empty parameter range"),
|
|
ParameterScanError::TooLarge => write!(f, "Parameter range is too large"),
|
|
ParameterScanError::ZeroStep => write!(f, "Zero is not a valid parameter step"),
|
|
ParameterScanError::StepRequired => write!(
|
|
f,
|
|
"A step size is required when the range bounds are \
|
|
floating point numbers. The step size can be specified \
|
|
with the '--parameter-step-size' parameter"
|
|
),
|
|
ParameterScanError::UnexpectedCommandNameCount(real, expected) => {
|
|
write!(
|
|
f,
|
|
"'--command-name' has been specified {} times. It has to appear exactly once, or exactly {} times (number of benchmarks)",
|
|
real, expected
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Error for ParameterScanError {}
|
|
|
|
#[derive(Debug)]
|
|
pub enum OptionsError<'a> {
|
|
EmptyRunsRange,
|
|
TooManyCommandNames(usize),
|
|
UnexpectedCommandNameCount(usize, usize),
|
|
NumericParsingError(&'a str, ParseIntError),
|
|
EmptyShell,
|
|
ShellParseError(shell_words::ParseError),
|
|
}
|
|
|
|
impl<'a> fmt::Display for OptionsError<'a> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match *self {
|
|
OptionsError::EmptyRunsRange => write!(f, "Empty runs range"),
|
|
OptionsError::TooManyCommandNames(n) => {
|
|
write!(f, "Too many --command-name options: expected {} at most", n)
|
|
}
|
|
OptionsError::UnexpectedCommandNameCount(real, expected) => {
|
|
write!(
|
|
f,
|
|
"'--command-name' has been specified {} times. It has to appear exactly once, or exactly {} times (number of benchmarks)",
|
|
real, expected
|
|
)
|
|
}
|
|
OptionsError::NumericParsingError(cmd, ref err) => write!(
|
|
f,
|
|
"Could not read numeric argument to '--{cmd}': {err}",
|
|
cmd = cmd,
|
|
err = err
|
|
),
|
|
OptionsError::EmptyShell => write!(f, "Empty command at --shell option"),
|
|
OptionsError::ShellParseError(ref err) => {
|
|
write!(f, "Could not parse --shell value as command line: {}", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Error for OptionsError<'a> {}
|