Unify TimingResult/TimerResult/Measurement

This commit is contained in:
David Peter authored and David Peter committed 2026-10-05 15:58:56 +02:00
1 parent f9aa299c0f
commit 42e75c1737
8 files changed
+272 -261

No files matched your search

+1 -1
View File
@@ -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
+51 -50
View File
@@ -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<CmdFailureAction>,
output_policy: &CommandOutputPolicy,
) -> Result<Measurement> {
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<Second> = vec![]; // TODO
let mut times_user: Vec<Second> = vec![];
let mut times_system: Vec<Second> = 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(&times_wall_clock),
time_user: mean(&times_user),
time_system: mean(&times_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<()> {
+35 -13
View File
@@ -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<S>(exit_status: &ExitStatus, serializer: S) -> Result<S::Ok, S::Error>
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<i32>,
// 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<Second> {
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::<Vec<_>>(),
)
}
/// 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::<Vec<_>>(),
)
}
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<f64> {
modified_zscores(
&self
+22 -24
View File
@@ -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 {
+6 -6
View File
@@ -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(),
+33 -32
View File
@@ -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: {
+120 -120
View File
@@ -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(),
+4 -15
View File
@@ -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<Measurement> {
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,
})
}