use std::process::ExitStatus; use serde::Serialize; use crate::quantity::statistics::{max, mean, median, min, modified_zscores, standard_deviation}; use crate::quantity::{serialize_information, serialize_time, Information, Time}; 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(), } } fn serialize_optional_information( value: &Option, serializer: S, ) -> Result where S: serde::Serializer, { match value { Some(value) => serialize_information(value, serializer), None => serializer.serialize_none(), } } /// Performance metric measurements and exit code for a single run #[derive(Debug, Clone, Default, Serialize, PartialEq)] pub struct Measurement { /// Elapsed wall clock time (real time) #[serde(serialize_with = "serialize_time")] pub time_wall_clock: Time, /// Time spent in user mode #[serde(serialize_with = "serialize_time")] pub time_user: Time, /// Time spent in kernel mode #[serde(serialize_with = "serialize_time")] pub time_system: Time, /// Peak resident set size, if available on this platform #[serde( skip_serializing_if = "Option::is_none", serialize_with = "serialize_optional_information" )] pub memory_peak_resident: Option, // The exit status of the process #[serde(rename = "exit_code", serialize_with = "serialize_exit_status")] pub exit_status: ExitStatus, } #[derive(Debug, Default, Clone, Serialize, PartialEq)] pub struct Measurements { pub measurements: Vec, } impl Measurements { pub fn new(measurements: Vec) -> Self { Self { measurements } } pub fn len(&self) -> usize { self.measurements.len() } pub fn is_empty(&self) -> bool { self.measurements.is_empty() } pub fn push(&mut self, measurement: Measurement) { self.measurements.push(measurement); } pub fn wall_clock_times(&self) -> impl Iterator + '_ { self.measurements.iter().map(|m| m.time_wall_clock) } /// The average wall clock time pub fn time_wall_clock_mean(&self) -> Time { mean(self.wall_clock_times()) } /// The standard deviation of all wall clock times. Not available if only one run has been performed pub fn stddev(&self) -> Option