mirror of
https://github.com/sharkdp/hyperfine.git
synced 2024-08-17 18:00:31 +03:00
Proper shell overhead computation
This commit is contained in:
parent
a1885ac746
commit
436bff7664
@ -165,12 +165,12 @@ impl<'a> Executor for ShellExecutor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MockExecutor<'a> {
|
pub struct MockExecutor {
|
||||||
shell: &'a Shell,
|
shell: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MockExecutor<'a> {
|
impl MockExecutor {
|
||||||
pub fn new(shell: &'a Shell) -> Self {
|
pub fn new(shell: Option<String>) -> Self {
|
||||||
MockExecutor { shell }
|
MockExecutor { shell }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ impl<'a> MockExecutor<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Executor for MockExecutor<'a> {
|
impl Executor for MockExecutor {
|
||||||
fn time_command(
|
fn time_command(
|
||||||
&self,
|
&self,
|
||||||
command: &Command<'_>,
|
command: &Command<'_>,
|
||||||
@ -217,9 +217,9 @@ impl<'a> Executor for MockExecutor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn time_overhead(&self) -> Second {
|
fn time_overhead(&self) -> Second {
|
||||||
match self.shell {
|
match &self.shell {
|
||||||
Shell::Default(_) => 0.0,
|
None => 0.0,
|
||||||
Shell::Custom(shell) => Self::extract_time(&shell[0]),
|
Some(shell) => Self::extract_time(shell),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,11 +141,10 @@ impl<'a> Benchmark<'a> {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
let run_preparation_command = || {
|
let run_preparation_command = || {
|
||||||
if let Some(ref cmd) = preparation_command {
|
preparation_command
|
||||||
self.run_preparation_command(cmd)
|
.as_ref()
|
||||||
} else {
|
.map(|cmd| self.run_preparation_command(cmd))
|
||||||
Ok(TimingResult::default())
|
.transpose()
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.run_setup_command(self.command.get_parameters().iter().cloned())?;
|
self.run_setup_command(self.command.get_parameters().iter().cloned())?;
|
||||||
@ -186,6 +185,8 @@ impl<'a> Benchmark<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let preparation_result = run_preparation_command()?;
|
let preparation_result = run_preparation_command()?;
|
||||||
|
let preparation_overhead =
|
||||||
|
preparation_result.map_or(0.0, |res| res.time_real + self.executor.time_overhead());
|
||||||
|
|
||||||
// Initial timing run
|
// Initial timing run
|
||||||
let (res, status) = self.executor.time_command(self.command, None)?;
|
let (res, status) = self.executor.time_command(self.command, None)?;
|
||||||
@ -193,7 +194,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
|
|
||||||
// Determine number of benchmark runs
|
// Determine number of benchmark runs
|
||||||
let runs_in_min_time = (self.options.min_benchmarking_time
|
let runs_in_min_time = (self.options.min_benchmarking_time
|
||||||
/ (res.time_real + preparation_result.time_real + self.executor.time_overhead()))
|
/ (res.time_real + self.executor.time_overhead() + preparation_overhead))
|
||||||
as u64;
|
as u64;
|
||||||
|
|
||||||
let count = {
|
let count = {
|
||||||
|
@ -33,7 +33,7 @@ impl<'a> Scheduler<'a> {
|
|||||||
|
|
||||||
pub fn run_benchmarks(&mut self) -> Result<()> {
|
pub fn run_benchmarks(&mut self) -> Result<()> {
|
||||||
let mut executor: Box<dyn Executor> = match self.options.executor_kind {
|
let mut executor: Box<dyn Executor> = match self.options.executor_kind {
|
||||||
ExecutorKind::Mock(ref shell) => Box::new(MockExecutor::new(shell)),
|
ExecutorKind::Mock(ref shell) => Box::new(MockExecutor::new(shell.clone())),
|
||||||
ExecutorKind::Shell(ref shell) => Box::new(ShellExecutor::new(shell, &self.options)),
|
ExecutorKind::Shell(ref shell) => Box::new(ShellExecutor::new(shell, &self.options)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ impl Default for CommandOutputPolicy {
|
|||||||
|
|
||||||
pub enum ExecutorKind {
|
pub enum ExecutorKind {
|
||||||
Shell(Shell),
|
Shell(Shell),
|
||||||
Mock(Shell),
|
Mock(Option<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ExecutorKind {
|
impl Default for ExecutorKind {
|
||||||
@ -276,8 +276,8 @@ impl Options {
|
|||||||
{
|
{
|
||||||
(false, Some(shell)) => ExecutorKind::Shell(Shell::from_str(shell)?),
|
(false, Some(shell)) => ExecutorKind::Shell(Shell::from_str(shell)?),
|
||||||
(false, None) => ExecutorKind::Shell(Shell::default()),
|
(false, None) => ExecutorKind::Shell(Shell::default()),
|
||||||
(true, Some(shell)) => ExecutorKind::Mock(Shell::from_str(shell)?),
|
(true, Some(shell)) => ExecutorKind::Mock(Some(shell.into())),
|
||||||
(true, None) => ExecutorKind::Mock(Shell::default()),
|
(true, None) => ExecutorKind::Mock(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
if matches.is_present("ignore-failure") {
|
if matches.is_present("ignore-failure") {
|
||||||
|
@ -189,7 +189,6 @@ fn returns_mean_time_in_correct_unit() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn performs_ten_runs_for_slow_commands() {
|
fn performs_ten_runs_for_slow_commands() {
|
||||||
hyperfine_debug()
|
hyperfine_debug()
|
||||||
.arg("--time-unit=millisecond")
|
|
||||||
.arg("sleep 0.5")
|
.arg("sleep 0.5")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
@ -199,7 +198,6 @@ fn performs_ten_runs_for_slow_commands() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn performs_three_seconds_of_benchmarking_for_fast_commands() {
|
fn performs_three_seconds_of_benchmarking_for_fast_commands() {
|
||||||
hyperfine_debug()
|
hyperfine_debug()
|
||||||
.arg("--time-unit=millisecond")
|
|
||||||
.arg("sleep 0.01")
|
.arg("sleep 0.01")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
@ -207,14 +205,33 @@ fn performs_three_seconds_of_benchmarking_for_fast_commands() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn takes_time_of_preparation_command_into_account() {
|
fn takes_shell_spawning_time_into_account_for_computing_number_of_runs() {
|
||||||
|
hyperfine_debug()
|
||||||
|
.arg("--shell=sleep 0.02")
|
||||||
|
.arg("sleep 0.01")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("100 runs"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn takes_preparation_command_into_account_for_computing_number_of_runs() {
|
||||||
hyperfine_debug()
|
hyperfine_debug()
|
||||||
.arg("--time-unit=millisecond")
|
|
||||||
.arg("--prepare=sleep 0.02")
|
.arg("--prepare=sleep 0.02")
|
||||||
.arg("sleep 0.01")
|
.arg("sleep 0.01")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
.stdout(predicate::str::contains("100 runs"));
|
.stdout(predicate::str::contains("100 runs"));
|
||||||
|
|
||||||
|
// Shell overhead needs to be added to both the prepare command and the actual command,
|
||||||
|
// leading to a total benchmark time of (prepare + shell + cmd + shell = 0.1 s)
|
||||||
|
hyperfine_debug()
|
||||||
|
.arg("--shell=sleep 0.01")
|
||||||
|
.arg("--prepare=sleep 0.03")
|
||||||
|
.arg("sleep 0.05")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("30 runs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user