diff --git a/src/benchmark/benchmark_result.rs b/src/benchmark/benchmark_result.rs index 662a079..826bcee 100644 --- a/src/benchmark/benchmark_result.rs +++ b/src/benchmark/benchmark_result.rs @@ -38,7 +38,7 @@ pub struct BenchmarkResult { impl BenchmarkResult { /// The average wall clock time pub fn mean_wall_clock_time(&self) -> Second { - self.measurements.mean() + self.measurements.time_wall_clock_mean() } /// The full command line of the program that is being benchmarked, possibly including a list of diff --git a/src/benchmark/executor.rs b/src/benchmark/executor.rs index cffa61f..f3816e5 100644 --- a/src/benchmark/executor.rs +++ b/src/benchmark/executor.rs @@ -2,7 +2,8 @@ use std::os::windows::process::CommandExt; use std::process::ExitStatus; -use crate::benchmark::quantity::mean; +use crate::benchmark::measurement::Measurement; +use crate::benchmark::measurement::Measurements; use crate::benchmark::quantity::Byte; use crate::benchmark::quantity::Second; use crate::command::Command; @@ -10,12 +11,9 @@ use crate::options::{ CmdFailureAction, CommandInputPolicy, CommandOutputPolicy, Options, OutputStyleOption, Shell, }; use crate::output::progress_bar::get_progress_bar; -use crate::quantity::{second, Information, Time, Zero}; use crate::timer::execute_and_measure; use crate::util::randomized_environment_offset; -use super::measurement::{Measurement, Measurements}; - use anyhow::{bail, Context, Result}; #[derive(Clone, Copy)] @@ -82,8 +80,20 @@ fn run_command_and_measure_common( let result = execute_and_measure(command) .with_context(|| format!("Failed to run command '{command_name}'"))?; - if !result.exit_status.success() { - use crate::util::exit_code::extract_exit_code; + if command_failure_action == CmdFailureAction::RaiseError && !result.exit_status.success() { + let when = match iteration { + BenchmarkIteration::NonBenchmarkRun => "a non-benchmark run".to_string(), + BenchmarkIteration::Warmup(0) => "the first warmup run".to_string(), + BenchmarkIteration::Warmup(i) => format!("warmup iteration {i}"), + BenchmarkIteration::Benchmark(0) => "the first benchmark run".to_string(), + BenchmarkIteration::Benchmark(i) => format!("benchmark iteration {i}"), + }; + bail!( + "{cause} in {when}. Use the '-i'/'--ignore-failure' option if you want to ignore this. \ + Alternatively, use the '--show-output' option to debug what went wrong.", + cause=result.exit_status.code().map_or( + "The process has been terminated by a signal".into(), + |c| format!("Command terminated with non-zero exit code {c}") let should_fail = match command_failure_action { CmdFailureAction::RaiseError => true, @@ -140,7 +150,7 @@ impl Executor for RawExecutor<'_> { command_failure_action: Option, output_policy: &CommandOutputPolicy, ) -> Result { - run_command_and_measure_common( + let result = run_command_and_measure_common( command.get_command()?, iteration, command_failure_action.unwrap_or_else(|| self.options.command_failure_action.clone()), @@ -149,15 +159,13 @@ impl Executor for RawExecutor<'_> { &command.get_command_line(), )?; - Ok(( - TimingResult { - time_wall_clock: result.time_wall_clock, - time_user: result.time_user, - time_system: result.time_system, - memory_usage_byte: result.memory_usage_byte, - }, - result.status, - )) + Ok(Measurement { + time_wall_clock: result.time_wall_clock, + time_user: result.time_user, + time_system: result.time_system, + peak_memory_usage: result.peak_memory_usage, + exit_status: result.exit_status, + }) } fn calibrate(&mut self) -> Result<()> { @@ -223,7 +231,7 @@ impl Executor for ShellExecutor<'_> { } } - if let Some(spawning_time) = self.shell_spawning_time { + if let Some(ref spawning_time) = self.shell_spawning_time { result.time_wall_clock = ensure_non_negative(result.time_wall_clock - spawning_time.time_wall_clock); result.time_user = ensure_non_negative(result.time_user - spawning_time.time_user); @@ -231,15 +239,13 @@ impl Executor for ShellExecutor<'_> { ensure_non_negative(result.time_system - spawning_time.time_system); } - Ok(( - TimingResult { - time_wall_clock: result.time_wall_clock, - time_user: result.time_user, - time_system: result.time_system, - memory_usage_byte: result.memory_usage_byte, - }, - result.status, - )) + Ok(Measurement { + time_wall_clock: result.time_wall_clock, + time_user: result.time_user, + time_system: result.time_system, + peak_memory_usage: result.peak_memory_usage, + exit_status: result.exit_status, + }) } /// Measure the average shell spawning time @@ -255,20 +261,18 @@ impl Executor for ShellExecutor<'_> { None }; - let mut times_wall_clock: Vec = vec![]; // TODO - let mut times_user: Vec = vec![]; - let mut times_system: Vec = vec![]; + let mut measurements = Measurements::default(); for _ in 0..COUNT { // Just run the shell without any command - let res = self.run_command_and_measure( + let measurement = self.run_command_and_measure( &Command::new(None, ""), BenchmarkIteration::NonBenchmarkRun, None, &CommandOutputPolicy::Null, ); - match res { + match measurement { Err(_) => { let shell_cmd = if cfg!(windows) { format!("{} /C \"\"", self.shell) @@ -281,10 +285,8 @@ impl Executor for ShellExecutor<'_> { shell_cmd ); } - Ok((r, _)) => { - times_wall_clock.push(r.time_wall_clock); - times_user.push(r.time_user); - times_system.push(r.time_system); + Ok(result) => { + measurements.push(result); } } @@ -297,18 +299,19 @@ impl Executor for ShellExecutor<'_> { bar.finish_and_clear() } - self.shell_spawning_time = Some(TimingResult { - time_wall_clock: mean(×_wall_clock), - time_user: mean(×_user), - time_system: mean(×_system), - memory_usage_byte: Byte::new(0), + self.shell_spawning_time = Some(Measurement { + time_wall_clock: measurements.time_wall_clock_mean(), + time_user: measurements.time_user_mean(), + time_system: measurements.time_system_mean(), + peak_memory_usage: measurements.peak_memory_usage_mean(), + exit_status: ExitStatus::default(), }); Ok(()) } fn time_overhead(&self) -> Second { - self.shell_spawning_time.unwrap().time_wall_clock + self.shell_spawning_time.as_ref().unwrap().time_wall_clock } } @@ -354,15 +357,13 @@ impl Executor for MockExecutor { ExitStatus::from_raw(0) }; - Ok(( - TimingResult { - time_wall_clock: Self::extract_time(command.get_command_line()), - time_user: Second::zero(), - time_system: Second::zero(), - memory_usage_byte: Byte::new(0), - }, - status, - )) + Ok(Measurement { + time_wall_clock: Self::extract_time(command.get_command_line()), + time_user: Second::zero(), + time_system: Second::zero(), + peak_memory_usage: Byte::new(0), + exit_status, + }) } fn calibrate(&mut self) -> Result<()> { diff --git a/src/benchmark/measurement.rs b/src/benchmark/measurement.rs index 86114a0..77e08d2 100644 --- a/src/benchmark/measurement.rs +++ b/src/benchmark/measurement.rs @@ -1,25 +1,39 @@ +use std::process::ExitStatus; + use serde::Serialize; use crate::benchmark::quantity::{max, mean, median, min, standard_deviation, Byte, Second}; use crate::outlier_detection::modified_zscores; +use crate::util::exit_code::extract_exit_code; + +fn serialize_exit_status(exit_status: &ExitStatus, serializer: S) -> Result +where + S: serde::Serializer, +{ + match extract_exit_code(*exit_status) { + Some(code) => serializer.serialize_i32(code), + None => serializer.serialize_unit(), + } +} /// Performance metric measurements and exit code for a single run -#[derive(Debug, Clone, Serialize, PartialEq)] +#[derive(Debug, Clone, Default, Serialize, PartialEq)] pub struct Measurement { /// Elapsed wall clock time (real time) - pub wall_clock_time: Second, + pub time_wall_clock: Second, /// Time spent in user mode - pub user_time: Second, + pub time_user: Second, /// Time spent in kernel mode - pub system_time: Second, + pub time_system: Second, /// Maximum memory usage of the process - pub memory_usage_byte: Byte, + pub peak_memory_usage: Byte, - /// Exit codes of the process - pub exit_code: Option, + // The exit status of the process + #[serde(serialize_with = "serialize_exit_status")] + pub exit_status: ExitStatus, } #[derive(Debug, Default, Clone, Serialize, PartialEq)] @@ -47,12 +61,12 @@ impl Measurements { pub fn wall_clock_times(&self) -> Vec { self.measurements .iter() - .map(|m| m.wall_clock_time) + .map(|m| m.time_wall_clock) .collect() } /// The average wall clock time - pub fn mean(&self) -> Second { + pub fn time_wall_clock_mean(&self) -> Second { mean(&self.wall_clock_times()) } @@ -83,27 +97,35 @@ impl Measurements { } /// The average user time - pub fn user_mean(&self) -> Second { + pub fn time_user_mean(&self) -> Second { mean( &self .measurements .iter() - .map(|m| m.user_time) + .map(|m| m.time_user) .collect::>(), ) } /// The average system time - pub fn system_mean(&self) -> Second { + pub fn time_system_mean(&self) -> Second { mean( &self .measurements .iter() - .map(|m| m.system_time) + .map(|m| m.time_system) .collect::>(), ) } + pub fn peak_memory_usage_mean(&self) -> Byte { + self.measurements + .iter() + .map(|m| m.peak_memory_usage) + .max_by(|a, b| a.partial_cmp(b).unwrap()) // TODO + .unwrap() // TODO + } + pub fn modified_zscores(&self) -> Vec { modified_zscores( &self diff --git a/src/benchmark/mod.rs b/src/benchmark/mod.rs index 7ab08b9..a6abd22 100644 --- a/src/benchmark/mod.rs +++ b/src/benchmark/mod.rs @@ -25,10 +25,7 @@ use crate::output::progress_bar::{ }; use crate::output::warnings::{OutlierWarningOptions, Warnings}; use crate::parameter::ParameterNameAndValue; -use crate::quantity::{byte, const_time_from_seconds, ratio, second, FormatQuantity, Time, Zero}; -use crate::util::exit_code::extract_exit_code; use benchmark_result::BenchmarkResult; -use measurement::{Measurement, Measurements}; use anyhow::{anyhow, Result}; use colored::*; @@ -273,20 +270,20 @@ impl<'a> Benchmark<'a> { if let Some(bar) = progress_bar.as_ref() { start_initial_measurement(bar, Instant::now()); } - let res = self.executor.run_command_and_measure( + let result = self.executor.run_command_and_measure( self.command, benchmark_iteration, None, output_policy, )?; - let success = res.exit_status.success(); + let success = result.exit_status.success(); if let Some(bar) = progress_bar.as_ref() { let time_unit = self .options .time_unit - .unwrap_or(res.time_wall_clock.suitable_unit()); - let estimate = res.time_wall_clock.format(time_unit); + .unwrap_or(result.time_wall_clock.suitable_unit()); + let estimate = result.time_wall_clock.format(time_unit); finish_initial_measurement( bar, format!("Current estimate: {}", estimate.to_string().green()), @@ -300,7 +297,7 @@ impl<'a> Benchmark<'a> { // Determine number of benchmark runs let runs_in_min_time = (self.options.min_benchmarking_time - / (res.time_wall_clock + / (result.time_wall_clock + self.executor.time_overhead() + preparation_overhead + conclusion_overhead)) @@ -321,11 +318,11 @@ impl<'a> Benchmark<'a> { // Save the first result measurements.push(Measurement { - wall_clock_time: res.time_wall_clock, - user_time: res.time_user, - system_time: res.time_system, - memory_usage_byte: res.memory_usage_byte, - exit_code: extract_exit_code(status), + time_wall_clock: result.time_wall_clock, + time_user: result.time_user, + time_system: result.time_system, + peak_memory_usage: result.peak_memory_usage, + exit_status: result.exit_status, }); all_succeeded = all_succeeded && success; @@ -341,7 +338,8 @@ impl<'a> Benchmark<'a> { let benchmark_iteration = BenchmarkIteration::Benchmark(i + 1); let msg = { - let mean = format_duration(measurements.mean(), self.options.time_unit); + let mean = + format_duration(measurements.time_wall_clock_mean(), self.options.time_unit); format!("Current estimate: {}", mean.to_string().green()) }; @@ -351,20 +349,20 @@ impl<'a> Benchmark<'a> { run_preparation_command(benchmark_iteration)?; - let res = self.executor.run_command_and_measure( + let result = self.executor.run_command_and_measure( self.command, benchmark_iteration, None, output_policy, )?; - let success = res.exit_status.success(); + let success = result.exit_status.success(); measurements.push(Measurement { - wall_clock_time: res.time_wall_clock, - user_time: res.time_user, - system_time: res.time_system, - memory_usage_byte: res.memory_usage_byte, - exit_code: extract_exit_code(status), + time_wall_clock: result.time_wall_clock, + time_user: result.time_user, + time_system: result.time_system, + peak_memory_usage: result.peak_memory_usage, + exit_status: result.exit_status, }); all_succeeded = all_succeeded && success; @@ -382,13 +380,13 @@ impl<'a> Benchmark<'a> { // Formatting and console output let (mean_str, time_unit) = - format_duration_unit(measurements.mean(), self.options.time_unit); + format_duration_unit(measurements.time_wall_clock_mean(), self.options.time_unit); let min_str = format_duration(measurements.min(), Some(time_unit)); let max_str = format_duration(measurements.max(), Some(time_unit)); let num_str = format!("{num_runs} runs", num_runs = measurements.len()); - let user_str = format_duration(measurements.user_mean(), Some(time_unit)); - let system_str = format_duration(measurements.system_mean(), Some(time_unit)); + let user_str = format_duration(measurements.time_user_mean(), Some(time_unit)); + let system_str = format_duration(measurements.time_system_mean(), Some(time_unit)); if self.options.output_style != OutputStyleOption::Disabled { if measurements.len() == 1 { diff --git a/src/benchmark/relative_speed.rs b/src/benchmark/relative_speed.rs index c427444..c088253 100644 --- a/src/benchmark/relative_speed.rs +++ b/src/benchmark/relative_speed.rs @@ -148,7 +148,7 @@ pub fn compute<'a>( #[cfg(test)] fn create_result(name: &str, mean: f64) -> BenchmarkResult { - use std::collections::BTreeMap; + use std::{collections::BTreeMap, process::ExitStatus}; use crate::benchmark::{ measurement::{Measurement, Measurements}, @@ -159,11 +159,11 @@ fn create_result(name: &str, mean: f64) -> BenchmarkResult { command: name.into(), measurements: Measurements { measurements: vec![Measurement { - wall_clock_time: Second::new(mean), - user_time: Second::new(mean), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(mean), + time_user: Second::new(mean), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }], }, parameters: BTreeMap::new(), diff --git a/src/export/csv.rs b/src/export/csv.rs index 014b9fe..ff07693 100644 --- a/src/export/csv.rs +++ b/src/export/csv.rs @@ -48,8 +48,8 @@ impl Exporter for CsvExporter { res.mean_wall_clock_time(), res.measurements.stddev().unwrap_or_default(), res.measurements.median(), - res.measurements.user_mean(), - res.measurements.system_mean(), + res.measurements.time_user_mean(), + res.measurements.time_system_mean(), res.measurements.min(), res.measurements.max(), ] { @@ -72,6 +72,7 @@ fn test_csv() { use crate::benchmark::quantity::{Byte, Second}; use std::collections::BTreeMap; + use std::process::ExitStatus; let exporter = CsvExporter::default(); @@ -80,25 +81,25 @@ fn test_csv() { command: String::from("command_a"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(7.0), - user_time: Second::new(7.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(7.0), + time_user: Second::new(7.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(8.0), - user_time: Second::new(8.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(8.0), + time_user: Second::new(8.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(12.0), - user_time: Second::new(12.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(12.0), + time_user: Second::new(12.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: { @@ -124,25 +125,25 @@ fn test_csv() { command: String::from("command_b"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(17.0), - user_time: Second::new(17.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(17.0), + time_user: Second::new(17.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(18.0), - user_time: Second::new(18.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(18.0), + time_user: Second::new(18.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(19.0), - user_time: Second::new(19.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(19.0), + time_user: Second::new(19.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: { diff --git a/src/export/tests.rs b/src/export/tests.rs index 5b873d7..2a0834b 100644 --- a/src/export/tests.rs +++ b/src/export/tests.rs @@ -31,25 +31,25 @@ fn test_markup_export_auto_ms() { command: String::from("sleep 0.1"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(0.09), - user_time: Second::new(0.09), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.09), + time_user: Second::new(0.09), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.10), - user_time: Second::new(0.10), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.10), + time_user: Second::new(0.10), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.14), - user_time: Second::new(0.14), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.14), + time_user: Second::new(0.14), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -58,25 +58,25 @@ fn test_markup_export_auto_ms() { command: String::from("sleep 2"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(2.0), - user_time: Second::new(2.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.0), + time_user: Second::new(2.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(3.0), - user_time: Second::new(3.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(3.0), + time_user: Second::new(3.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(4.0), - user_time: Second::new(4.0), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(4.0), + time_user: Second::new(4.0), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -130,25 +130,25 @@ fn test_markup_export_auto_s() { command: String::from("sleep 2"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(2.1), - user_time: Second::new(2.1), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.1), + time_user: Second::new(2.1), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(2.2), - user_time: Second::new(2.2), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.2), + time_user: Second::new(2.2), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(2.3), - user_time: Second::new(2.3), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.3), + time_user: Second::new(2.3), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -157,25 +157,25 @@ fn test_markup_export_auto_s() { command: String::from("sleep 0.1"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(0.1), - user_time: Second::new(0.1), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.1), + time_user: Second::new(0.1), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.2), - user_time: Second::new(0.2), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.2), + time_user: Second::new(0.2), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.3), - user_time: Second::new(0.3), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.3), + time_user: Second::new(0.3), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -229,25 +229,25 @@ fn test_markup_export_manual_ms() { command: String::from("sleep 2"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(2.1), - user_time: Second::new(2.1), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.1), + time_user: Second::new(2.1), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(2.2), - user_time: Second::new(2.2), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.2), + time_user: Second::new(2.2), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(2.3), - user_time: Second::new(2.3), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.3), + time_user: Second::new(2.3), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -256,25 +256,25 @@ fn test_markup_export_manual_ms() { command: String::from("sleep 0.1"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(0.1), - user_time: Second::new(0.1), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.1), + time_user: Second::new(0.1), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.2), - user_time: Second::new(0.2), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.2), + time_user: Second::new(0.2), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.3), - user_time: Second::new(0.3), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.3), + time_user: Second::new(0.3), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -327,25 +327,25 @@ fn test_markup_export_manual_s() { command: String::from("sleep 2"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(2.01), - user_time: Second::new(2.01), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.01), + time_user: Second::new(2.01), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(2.02), - user_time: Second::new(2.02), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.02), + time_user: Second::new(2.02), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(2.03), - user_time: Second::new(2.03), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(2.03), + time_user: Second::new(2.03), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), @@ -354,25 +354,25 @@ fn test_markup_export_manual_s() { command: String::from("sleep 0.1"), measurements: Measurements::new(vec![ Measurement { - wall_clock_time: Second::new(0.11), - user_time: Second::new(0.11), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.11), + time_user: Second::new(0.11), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.12), - user_time: Second::new(0.12), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.12), + time_user: Second::new(0.12), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, Measurement { - wall_clock_time: Second::new(0.13), - user_time: Second::new(0.13), - system_time: Second::zero(), - memory_usage_byte: Byte::new(1024), - exit_code: Some(0), + time_wall_clock: Second::new(0.13), + time_user: Second::new(0.13), + time_system: Second::zero(), + peak_memory_usage: Byte::new(1024), + exit_status: ExitStatus::default(), }, ]), parameters: BTreeMap::new(), diff --git a/src/timer/mod.rs b/src/timer/mod.rs index 2a7f35e..3807a04 100644 --- a/src/timer/mod.rs +++ b/src/timer/mod.rs @@ -16,7 +16,7 @@ use std::os::fd::AsFd; #[cfg(target_os = "windows")] use windows_sys::Win32::System::Threading::CREATE_SUSPENDED; -use crate::benchmark::quantity::{Byte, Second}; +use crate::benchmark::measurement::Measurement; use wall_clock_timer::WallClockTimer; use std::io::Read; @@ -24,17 +24,6 @@ use std::process::{ChildStdout, Command}; use anyhow::Result; -/// Used to indicate the result of running a command -#[derive(Debug, Copy, Clone)] -pub struct TimerResult { - pub time_wall_clock: Second, - pub time_user: Second, - pub time_system: Second, - pub memory_usage_byte: Byte, - /// The exit status of the process - pub status: ExitStatus, -} - /// Discard the output of a child process. fn discard(output: ChildStdout) { const CHUNK_SIZE: usize = 64 << 10; @@ -93,14 +82,14 @@ pub fn execute_and_measure(mut command: Command) -> Result { discard(output); } - let (status, time_user, time_system, memory_usage_byte) = cpu_timer.stop(child)?; + let (exit_status, time_user, time_system, memory_usage_byte) = cpu_timer.stop(child)?; let time_wall_clock = wallclock_timer.stop(); - Ok(TimerResult { + Ok(Measurement { time_wall_clock, time_user, time_system, - peak_memory_usage, + peak_memory_usage: memory_usage_byte, exit_status, }) }