Files
hyperfine/src/benchmark/scheduler.rs
T

144 lines
3.9 KiB
Rust
Raw Normal View History

2022-02-20 13:44:34 +01:00
use super::benchmark_result::BenchmarkResult;
use super::executor::{Executor, MockExecutor, RawExecutor, ShellExecutor};
use super::Benchmark;
2022-02-20 13:44:34 +01:00
use crate::command::Commands;
2022-02-07 21:03:23 +01:00
use crate::export::ExportManager;
use crate::options::{ExecutorKind, Options};
2022-02-07 21:03:23 +01:00
2022-02-21 08:46:10 +01:00
use anyhow::Result;
2022-02-20 13:44:34 +01:00
2022-02-20 14:04:37 +01:00
pub struct Scheduler<'a> {
commands: &'a Commands<'a>,
options: &'a Options,
export_manager: &'a ExportManager,
results: Vec<BenchmarkResult>,
}
impl<'a> Scheduler<'a> {
pub fn new(
commands: &'a Commands,
options: &'a Options,
export_manager: &'a ExportManager,
) -> Self {
Self {
commands,
options,
export_manager,
results: vec![],
2022-02-20 13:44:34 +01:00
}
}
2022-02-20 14:04:37 +01:00
pub fn run_benchmarks(&mut self) -> Result<()> {
2022-02-22 08:36:56 +01:00
let mut executor: Box<dyn Executor> = match self.options.executor_kind {
ExecutorKind::Raw => Box::new(RawExecutor::new(self.options)),
2022-02-22 08:58:57 +01:00
ExecutorKind::Mock(ref shell) => Box::new(MockExecutor::new(shell.clone())),
2022-02-22 10:13:06 +01:00
ExecutorKind::Shell(ref shell) => Box::new(ShellExecutor::new(shell, self.options)),
2022-02-22 08:36:56 +01:00
};
executor.calibrate()?;
2022-02-20 13:44:34 +01:00
for (number, cmd) in self.commands.iter().enumerate() {
self.results.push(
Benchmark::new(number, cmd, self.options, &*executor).run(self.results.first())?,
);
2022-02-20 14:04:37 +01:00
// We export results after each individual benchmark, because
// we would risk losing them if a later benchmark fails.
self.export_manager.write_results(&self.results, true)?;
2022-02-20 14:04:37 +01:00
}
Ok(())
2022-02-20 14:04:37 +01:00
}
pub fn final_export(&self) -> Result<()> {
self.export_manager.write_results(&self.results, false)
}
2022-02-20 13:44:34 +01:00
}
2024-12-29 13:40:05 +01:00
#[cfg(test)]
fn generate_results(args: &[&'static str]) -> Result<Vec<BenchmarkResult>> {
use crate::cli::get_cli_arguments;
let args = ["hyperfine", "--debug-mode", "--style=none"]
.iter()
2024-12-29 13:57:53 +01:00
.chain(args);
2024-12-29 13:40:05 +01:00
let cli_arguments = get_cli_arguments(args);
let mut options = Options::from_cli_arguments(&cli_arguments)?;
assert_eq!(options.executor_kind, ExecutorKind::Mock(None));
let commands = Commands::from_cli_arguments(&cli_arguments)?;
let export_manager = ExportManager::from_cli_arguments(&cli_arguments, options.metrics[0])?;
2024-12-29 13:40:05 +01:00
options.validate_against_command_list(&commands)?;
let mut scheduler = Scheduler::new(&commands, &options, &export_manager);
scheduler.run_benchmarks()?;
Ok(scheduler.results)
}
#[test]
fn scheduler_basic() -> Result<()> {
insta::assert_yaml_snapshot!(generate_results(&["--runs=2", "sleep 0.123", "sleep 0.456"])?, @r#"
- command: sleep 0.123
2026-10-05 14:15:34 +02:00
measurements:
2026-10-05 14:16:56 +02:00
- time_wall_clock:
value: 0.123
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_user:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_system:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
memory_peak_resident:
2026-10-05 14:16:56 +02:00
value: 0
2026-10-05 14:17:14 +02:00
unit: byte
2026-10-05 14:14:25 +02:00
exit_code: 0
2026-10-05 14:16:56 +02:00
- time_wall_clock:
value: 0.123
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_user:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_system:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
memory_peak_resident:
2026-10-05 14:16:56 +02:00
value: 0
2026-10-05 14:17:14 +02:00
unit: byte
2026-10-05 14:14:25 +02:00
exit_code: 0
2024-12-29 13:40:05 +01:00
- command: sleep 0.456
2026-10-05 14:15:34 +02:00
measurements:
2026-10-05 14:16:56 +02:00
- time_wall_clock:
value: 0.456
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_user:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_system:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
memory_peak_resident:
2026-10-05 14:16:56 +02:00
value: 0
2026-10-05 14:17:14 +02:00
unit: byte
2026-10-05 14:14:25 +02:00
exit_code: 0
2026-10-05 14:16:56 +02:00
- time_wall_clock:
value: 0.456
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_user:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
2026-10-05 14:16:56 +02:00
time_system:
value: 0
2026-10-05 14:17:14 +02:00
unit: second
memory_peak_resident:
2026-10-05 14:16:56 +02:00
value: 0
2026-10-05 14:17:14 +02:00
unit: byte
2026-10-05 14:14:25 +02:00
exit_code: 0
2024-12-29 13:40:05 +01:00
"#);
Ok(())
}