From 914d5cbc5981b6338cb78141cc539dff9ed24ad8 Mon Sep 17 00:00:00 2001 From: David Peter Date: Mon, 5 Oct 2026 14:15:49 +0200 Subject: [PATCH] Units --- src/benchmark/measurement.rs | 2 +- src/benchmark/mod.rs | 1 + src/benchmark/quantity.rs | 103 +++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/benchmark/quantity.rs diff --git a/src/benchmark/measurement.rs b/src/benchmark/measurement.rs index 2955220..5940bf7 100644 --- a/src/benchmark/measurement.rs +++ b/src/benchmark/measurement.rs @@ -9,7 +9,7 @@ use crate::{ }; /// Performance metric measurements and exit code for a single run -#[derive(Debug, Default, Clone, Serialize, PartialEq)] +#[derive(Debug, Clone, Serialize, PartialEq)] pub struct Measurement { /// Elapsed wall clock time (real time) pub wall_clock_time: Second, diff --git a/src/benchmark/mod.rs b/src/benchmark/mod.rs index dc5fb45..c41771a 100644 --- a/src/benchmark/mod.rs +++ b/src/benchmark/mod.rs @@ -1,6 +1,7 @@ pub mod benchmark_result; pub mod executor; pub mod measurement; +pub mod quantity; pub mod relative_speed; pub mod scheduler; diff --git a/src/benchmark/quantity.rs b/src/benchmark/quantity.rs new file mode 100644 index 0000000..2a8ae10 --- /dev/null +++ b/src/benchmark/quantity.rs @@ -0,0 +1,103 @@ +use std::fmt::{self, Display, Formatter}; + +use serde::Serialize; + +#[derive(Debug, Clone, Serialize, PartialEq)] +enum MetricPrefix { + Nano, + Micro, + Milli, + None, +} + +impl Display for MetricPrefix { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + MetricPrefix::Nano => write!(f, "n"), + MetricPrefix::Micro => write!(f, "ยต"), + MetricPrefix::Milli => write!(f, "m"), + MetricPrefix::None => Ok(()), + } + } +} + +#[derive(Debug, Clone, Serialize, PartialEq)] +enum BinaryPrefix { + None, + Kibi, + Mebi, + Gibi, + Tebi, +} + +impl Display for BinaryPrefix { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + BinaryPrefix::None => Ok(()), + BinaryPrefix::Kibi => write!(f, "Ki"), + BinaryPrefix::Mebi => write!(f, "Mi"), + BinaryPrefix::Gibi => write!(f, "Gi"), + BinaryPrefix::Tebi => write!(f, "Ti"), + } + } +} + +#[derive(Debug, Clone, Serialize, PartialEq)] +pub enum Unit { + Second(MetricPrefix), + Byte(BinaryPrefix), +} + +pub const SECOND: Unit = Unit::Second(MetricPrefix::None); +pub const MILLISECOND: Unit = Unit::Second(MetricPrefix::Milli); +pub const MICROSECOND: Unit = Unit::Second(MetricPrefix::Micro); +pub const BYTE: Unit = Unit::Byte(BinaryPrefix::None); + +impl Display for Unit { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Unit::Second(prefix) => write!(f, "{prefix}s",), + Unit::Byte(prefix) => write!(f, "{prefix}B"), + } + } +} + +#[derive(Debug, Clone, Serialize, PartialEq)] +pub struct Quantity { + value: Value, + unit: Unit, +} + +impl Quantity { + pub fn new(value: Value, unit: Unit) -> Self { + Self { value, unit } + } +} + +impl Display for Quantity { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{} {}", self.value, self.unit) + } +} + +pub fn mean(values: &[Quantity]) -> Quantity { + statistical::mean(values).unwrap() +} + +pub type Time = Quantity; +pub type Memory = Quantity; + +#[test] +fn basic() { + let time = Time { + value: 123.4, + unit: Unit::Second(MetricPrefix::Milli), + }; + assert_eq!(time.to_string(), "123.4 ms"); + + let peak_memory_usage = Memory { + value: 8, + unit: Unit::Byte(BinaryPrefix::Kibi), + }; + assert_eq!(peak_memory_usage.to_string(), "8 KiB"); +}