Add --setup (-s) option, like --prepare but runs once per batch

Add a --setup option for the use-case of wanting to do one-off setup
before a set of benchmarks, not the once-per-test setup that --prepare
does. This is useful for the cases noted in the updated documentation.

Per the feedback on https://github.com/sharkdp/hyperfine/pull/448 this
new "--setup" option will steal the "-s" short option from
"--style" (initially this was called "--build" and used the
non-conflicting "-b").

Potential future work:

I'd prefer if this and --cleanup took N number of commands, so you
could do e.g.:

    hyperfine -L rev master,next \
        -b 'git worktree add /tmp/test-{r}'  \
        -b 'make -C /tmp/test-{r} all'  \
	'make -C /tmp/test-{r} test' \
	-c 'git worktree remove /tmp/test-{r}'

I.e. a shortcut around not providing these with &&, which makes things
a bit more readable.

But the --cleanup option doesn't do that, so let's just go with what
it's doing for consistency, so for this you'll now need to do:

    hyperfine -L rev master,next \
        -b 'git worktree add /tmp/test-{r} &&
	    make -C /tmp/test-{r} all'  \
	'make -C /tmp/test-{r} test' \
	-c 'git worktree remove /tmp/test-{r}'
This commit is contained in:
Ævar Arnfjörð Bjarmason authored and David Peter committed 2021-11-16 21:36:35 +01:00
1 parent abd0d335ab
commit 017d55a4a1
7 files changed
+103 -3

No files matched your search

+14 -1
View File
@@ -73,6 +73,20 @@ fn build_app() -> App<'static, 'static> {
.help("Perform exactly NUM runs for each command. If this option is not specified, \
hyperfine automatically determines the number of runs."),
)
.arg(
Arg::with_name("setup")
.long("setup")
.short("s")
.takes_value(true)
.number_of_values(1)
.value_name("CMD")
.help(
"Execute CMD before each set of timing runs. This is useful for \
compiling your software with the provided parameters, or to do any \
other work that should happen once before a series of benchmark runs,\
not every time as would happen with the --prepare option."
),
)
.arg(
Arg::with_name("prepare")
.long("prepare")
@@ -155,7 +169,6 @@ fn build_app() -> App<'static, 'static> {
.arg(
Arg::with_name("style")
.long("style")
.short("s")
.takes_value(true)
.value_name("TYPE")
.possible_values(&["auto", "basic", "full", "nocolor", "color", "none"])
+18
View File
@@ -185,6 +185,18 @@ fn run_intermediate_command(
})
}
/// Run the command specified by `--setup`.
fn run_setup_command(
shell: &Shell,
command: &Option<Command<'_>>,
show_output: bool,
) -> io::Result<TimingResult> {
let error_output = "The setup command terminated with a non-zero exit code. \
Append ' || true' to the command if you are sure that this can be ignored.";
run_intermediate_command(shell, command, show_output, error_output)
}
/// Run the command specified by `--prepare`.
fn run_preparation_command(
shell: &Shell,
@@ -263,6 +275,12 @@ pub fn run_benchmark(
Command::new_parametrized(None, preparation_command, cmd.get_parameters().clone())
});
// Run setup command
let setup_cmd = options.setup_command.as_ref().map(|setup_command| {
Command::new_parametrized(None, setup_command, cmd.get_parameters().clone())
});
run_setup_command(&options.shell, &setup_cmd, options.show_output)?;
// Warmup phase
if options.warmup_count > 0 {
let progress_bar = if options.output_style != OutputStyleOption::Disabled {
+2
View File
@@ -193,6 +193,8 @@ fn build_hyperfine_options<'a>(
(None, None) => {}
};
options.setup_command = matches.value_of("setup").map(String::from);
options.preparation_command = matches
.values_of("prepare")
.map(|values| values.map(String::from).collect::<Vec<String>>());
+4
View File
@@ -114,6 +114,9 @@ pub struct HyperfineOptions {
/// Whether or not to ignore non-zero exit codes
pub failure_action: CmdFailureAction,
/// Command to run before each batch of timing runs
pub setup_command: Option<String>,
/// Command to run before each timing run
pub preparation_command: Option<Vec<String>>,
@@ -146,6 +149,7 @@ impl Default for HyperfineOptions {
runs: Runs::default(),
min_time_sec: 3.0,
failure_action: CmdFailureAction::RaiseError,
setup_command: None,
preparation_command: None,
cleanup_command: None,
output_style: OutputStyleOption::Full,