mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-10-31 16:40:18 +00:00
Add support for one run with --runs=1
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.
This commit is contained in:
1 parent
4b419c6ab4
commit
bffd476128
4 files changed
+27
-14
No files matched your search
+14
-2
@@ -391,7 +391,10 @@ pub fn run_benchmark(
|
||||
// Compute statistical quantities
|
||||
let t_num = times_real.len();
|
||||
let t_mean = mean(×_real);
|
||||
let t_stddev = standard_deviation(×_real, Some(t_mean));
|
||||
let mut t_stddev = 0.0;
|
||||
if times_real.len() != 1 {
|
||||
t_stddev = standard_deviation(×_real, Some(t_mean));
|
||||
}
|
||||
let t_median = median(×_real);
|
||||
let t_min = min(×_real);
|
||||
let t_max = max(×_real);
|
||||
@@ -409,7 +412,16 @@ pub fn run_benchmark(
|
||||
let user_str = format_duration(user_mean, Some(time_unit));
|
||||
let system_str = format_duration(system_mean, Some(time_unit));
|
||||
|
||||
if options.output_style != OutputStyleOption::Disabled {
|
||||
if options.output_style != OutputStyleOption::Disabled && times_real.len() == 1 {
|
||||
println!(
|
||||
" Time ({} ≡): {:>8} {:>8} [User: {}, System: {}]",
|
||||
"abs".green().bold(),
|
||||
mean_str.green().bold(),
|
||||
" ".to_string(), // alignment
|
||||
user_str.blue(),
|
||||
system_str.blue()
|
||||
);
|
||||
} else if options.output_style != OutputStyleOption::Disabled {
|
||||
println!(
|
||||
" Time ({} ± {}): {:>8} ± {:>8} [User: {}, System: {}]",
|
||||
"mean".green().bold(),
|
||||
|
||||
@@ -57,7 +57,6 @@ impl Error for ParameterScanError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OptionsError<'a> {
|
||||
RunsBelowTwo,
|
||||
EmptyRunsRange,
|
||||
TooManyCommandNames(usize),
|
||||
UnexpectedCommandNameCount(usize, usize),
|
||||
@@ -70,7 +69,6 @@ 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::RunsBelowTwo => write!(f, "Number of runs below two"),
|
||||
OptionsError::TooManyCommandNames(n) => {
|
||||
write!(f, "Too many --command-name options: expected {} at most", n)
|
||||
}
|
||||
|
||||
@@ -171,17 +171,9 @@ fn build_hyperfine_options<'a>(
|
||||
}
|
||||
|
||||
match (min_runs, max_runs) {
|
||||
(Some(min), _) if min < 2 => {
|
||||
// We need at least two runs to compute a variance.
|
||||
return Err(OptionsError::RunsBelowTwo);
|
||||
}
|
||||
(Some(min), None) => {
|
||||
options.runs.min = min;
|
||||
}
|
||||
(_, Some(max)) if max < 2 => {
|
||||
// We need at least two runs to compute a variance.
|
||||
return Err(OptionsError::RunsBelowTwo);
|
||||
}
|
||||
(None, Some(max)) => {
|
||||
// Since the minimum was not explicit we lower it if max is below the default min.
|
||||
options.runs.min = cmp::min(options.runs.min, max);
|
||||
|
||||
@@ -23,12 +23,12 @@ fn hyperfine_runs_successfully() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn at_least_two_runs_are_required() {
|
||||
fn one_run_is_supported() {
|
||||
hyperfine()
|
||||
.arg("--runs=1")
|
||||
.arg("echo dummy benchmark")
|
||||
.assert()
|
||||
.failure();
|
||||
.success();
|
||||
}
|
||||
|
||||
struct ExecutionOrderTest {
|
||||
@@ -109,6 +109,17 @@ impl Default for ExecutionOrderTest {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn benchmarks_are_executed_sequentially_one() {
|
||||
ExecutionOrderTest::new()
|
||||
.arg("--runs=1")
|
||||
.command("command 1")
|
||||
.command("command 2")
|
||||
.expect_output("command 1")
|
||||
.expect_output("command 2")
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn benchmarks_are_executed_sequentially() {
|
||||
ExecutionOrderTest::new()
|
||||
|
||||
Reference in new issue
Block a user