diff --git a/src/hyperfine/app.rs b/src/hyperfine/app.rs index d5635a1..3f6c7f2 100644 --- a/src/hyperfine/app.rs +++ b/src/hyperfine/app.rs @@ -76,10 +76,14 @@ fn build_app() -> App<'static, 'static> { .long("prepare") .short("p") .takes_value(true) + .multiple(true) + .number_of_values(1) .value_name("CMD") .help( - "Execute CMD before each timing run. This is useful for \ - clearing disk caches, for example.", + "Execute CMD before each timing run. For example, this is \ + useful for clearing disk caches. This can be mentioned \ + out multiple time for each command or only one time for \ + all command.", ), ) .arg( diff --git a/src/hyperfine/benchmark.rs b/src/hyperfine/benchmark.rs index f7547fd..3ce3e76 100644 --- a/src/hyperfine/benchmark.rs +++ b/src/hyperfine/benchmark.rs @@ -234,13 +234,17 @@ pub fn run_benchmark( ); // Run init command - let prepare_cmd = options - .preparation_command - .as_ref() - .map(|preparation_command| match cmd.get_parameter() { - Some((param, value)) => Command::new_parametrized(preparation_command, param, value), - None => Command::new(preparation_command), - }); + let mut prepare_cmd = None; + if let Some(values) = &options.preparation_command { + if num >= values.len() { + prepare_cmd = Some(new_command_from_get_parameter( + cmd, + &values[values.len() - 1], + )); + } else { + prepare_cmd = Some(new_command_from_get_parameter(cmd, &values[num])); + } + }; let prepare_res = run_preparation_command(&options.shell, &prepare_cmd, options.show_output)?; // Initial timing run @@ -404,3 +408,14 @@ pub fn run_benchmark( cmd.get_parameter().map(|p| p.1), )) } + +// Get out new Command from a Command and preparation command +fn new_command_from_get_parameter<'a>( + cmd: &Command<'a>, + preparation_command: &'a str, +) -> Command<'a> { + match cmd.get_parameter() { + Some((param, value)) => Command::new_parametrized(preparation_command, param, value), + None => Command::new(preparation_command), + } +} diff --git a/src/hyperfine/timer/windows_timer.rs b/src/hyperfine/timer/windows_timer.rs index 2ddfc95..b0ac1bf 100644 --- a/src/hyperfine/timer/windows_timer.rs +++ b/src/hyperfine/timer/windows_timer.rs @@ -65,7 +65,8 @@ fn get_cpu_times(handle: RawHandle) -> CPUTimes { // Extract times as laid out here: https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure // Both user_time and kernel_time are spans that the proces spent in either. let user: i64 = (((user_time.dwHighDateTime as i64) << 32) - + user_time.dwLowDateTime as i64) / HUNDRED_NS_PER_MS; + + user_time.dwLowDateTime as i64) + / HUNDRED_NS_PER_MS; let kernel: i64 = (((kernel_time.dwHighDateTime as i64) << 32) + kernel_time.dwLowDateTime as i64) / HUNDRED_NS_PER_MS; diff --git a/src/hyperfine/types.rs b/src/hyperfine/types.rs index d7d0038..3888651 100644 --- a/src/hyperfine/types.rs +++ b/src/hyperfine/types.rs @@ -145,7 +145,7 @@ pub struct HyperfineOptions { pub failure_action: CmdFailureAction, /// Command to run before each timing run - pub preparation_command: Option, + pub preparation_command: Option>, /// Command to run after each benchmark pub cleanup_command: Option, diff --git a/src/main.rs b/src/main.rs index 8c520bc..52f795e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -113,7 +113,11 @@ fn build_hyperfine_options(matches: &ArgMatches<'_>) -> Result {} }; - options.preparation_command = matches.value_of("prepare").map(String::from); + if let Some(values) = matches.values_of("prepare") { + options.preparation_command = Some(values.map(String::from).collect::>()); + } else { + options.preparation_command = None; + } options.cleanup_command = matches.value_of("cleanup").map(String::from);