This commit is contained in:
David Peter authored and David Peter committed 2026-10-05 16:00:48 +02:00
1 parent 3a2c8ab177
commit 9c2ee56cba
8 files changed
+59 -46

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ use crate::options::{
CmdFailureAction, CommandInputPolicy, CommandOutputPolicy, Options, OutputStyleOption, Shell,
};
use crate::output::progress_bar::get_progress_bar;
use crate::quantity::{second, Information, Quantity, Time};
use crate::quantity::{second, Information, Time, Zero};
use crate::timer::execute_and_measure;
use crate::util::randomized_environment_offset;
+1 -1
View File
@@ -86,7 +86,7 @@ impl Measurements {
/// The median wall clock time
pub fn median(&self) -> Time {
median(&self.wall_clock_times().collect::<Vec<_>>())
median(self.wall_clock_times())
}
/// The minimum wall clock time
+1 -1
View File
@@ -22,7 +22,7 @@ use crate::output::progress_bar::{
};
use crate::output::warnings::{OutlierWarningOptions, Warnings};
use crate::parameter::ParameterNameAndValue;
use crate::quantity::{self, const_time_from_seconds, Quantity, Time};
use crate::quantity::{self, const_time_from_seconds, FormatQuantity, Time, Zero};
use benchmark_result::BenchmarkResult;
use anyhow::{anyhow, Result};
+1 -1
View File
@@ -3,7 +3,7 @@ use std::cmp::Ordering;
use super::benchmark_result::BenchmarkResult;
use crate::{
options::SortOrder,
quantity::{self, Ratio, Time, Quantity},
quantity::{self, Ratio, Time, Zero},
};
#[derive(Debug)]
+2 -2
View File
@@ -5,7 +5,7 @@ use csv::WriterBuilder;
use super::Exporter;
use crate::benchmark::benchmark_result::BenchmarkResult;
use crate::options::SortOrder;
use crate::quantity::{Quantity, TimeUnit};
use crate::quantity::{FormatQuantity, TimeUnit};
use anyhow::Result;
@@ -71,7 +71,7 @@ impl Exporter for CsvExporter {
fn test_csv() {
use crate::benchmark::benchmark_result::Parameter;
use crate::benchmark::measurement::{Measurement, Measurements};
use crate::quantity::{byte, second, Information, Quantity, Time};
use crate::quantity::{byte, second, Information, Time, Zero};
use std::collections::BTreeMap;
use std::process::ExitStatus;
+1 -1
View File
@@ -3,7 +3,7 @@ use crate::benchmark::benchmark_result::BenchmarkResult;
use crate::benchmark::measurement::{Measurement, Measurements};
use crate::export::asciidoc::AsciidocExporter;
use crate::export::orgmode::OrgmodeExporter;
use crate::quantity::{byte, second, Information, Quantity, Time, TimeUnit};
use crate::quantity::{byte, second, Information, Time, TimeUnit, Zero};
use crate::{export::markdown::MarkdownExporter, options::SortOrder};
use std::collections::BTreeMap;
use std::process::ExitStatus;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::fmt;
use crate::benchmark::MIN_EXECUTION_TIME;
use crate::quantity::{Time, Quantity};
use crate::quantity::{FormatQuantity, Time};
pub struct OutlierWarningOptions {
pub warmup_in_use: bool,
+51 -38
View File
@@ -1,5 +1,6 @@
use core::f64;
use std::marker::PhantomData;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Div;
@@ -8,21 +9,20 @@ use serde::Serializer;
use uom::num_traits;
use uom::si;
pub use uom::si::information::{byte, gibibyte, kibibyte, mebibyte, tebibyte};
pub use uom::si::ratio::ratio;
pub use uom::si::time::{hour, microsecond, millisecond, minute, nanosecond, second};
pub use si::f64::{Information, Ratio, Time};
pub use si::information::{byte, gibibyte, kibibyte, mebibyte, tebibyte};
pub use si::ratio::ratio;
pub use si::time::{hour, microsecond, millisecond, minute, nanosecond, second};
pub use uom::num_traits::Zero;
pub use units::{InformationUnit, IsUnit, TimeUnit};
mod units;
pub trait Quantity {
pub trait FormatQuantity {
type Unit;
fn zero() -> Self;
fn suitable_unit(&self) -> Self::Unit;
fn format_with_precision(&self, unit: Self::Unit, precision: usize) -> String;
@@ -31,13 +31,9 @@ pub trait Quantity {
fn format_value(&self, unit: Self::Unit) -> String;
}
impl Quantity for Time {
impl FormatQuantity for Time {
type Unit = TimeUnit;
fn zero() -> Time {
Time::new::<second>(0.0)
}
fn suitable_unit(&self) -> TimeUnit {
if *self < Time::new::<millisecond>(1.0) {
TimeUnit::MicroSecond
@@ -81,13 +77,9 @@ pub const fn const_time_from_seconds(value: f64) -> Time {
}
}
impl Quantity for Information {
impl FormatQuantity for Information {
type Unit = InformationUnit;
fn zero() -> Information {
Information::new::<byte>(0.0)
}
fn suitable_unit(&self) -> InformationUnit {
if *self < Information::new::<kibibyte>(1.0) {
InformationUnit::Byte
@@ -120,6 +112,26 @@ impl Quantity for Information {
}
}
pub fn serialize_time<S>(t: &Time, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = s.serialize_struct("Time", 3)?;
state.serialize_field("value", &t.get::<second>())?;
state.serialize_field("unit", "second")?;
state.end()
}
pub fn serialize_information<S>(i: &Information, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = s.serialize_struct("Information", 3)?;
state.serialize_field("value", &i.get::<byte>())?;
state.serialize_field("unit", "byte")?;
state.end()
}
pub trait UnsafeRawValue {
fn unsafe_raw_value(&self) -> f64;
fn unsafe_from_raw_value(value: f64) -> Self;
@@ -145,26 +157,6 @@ impl UnsafeRawValue for Information {
}
}
pub fn serialize_time<S>(t: &Time, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = s.serialize_struct("Time", 3)?;
state.serialize_field("value", &t.value)?;
state.serialize_field("unit", "second")?;
state.end()
}
pub fn serialize_information<S>(i: &Information, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = s.serialize_struct("Information", 3)?;
state.serialize_field("value", &i.value)?;
state.serialize_field("unit", "byte")?;
state.end()
}
macro_rules! quantity_fn {
($name:ident, $unwrapped_values:ident, $body:expr) => {
pub fn $name<Q: UnsafeRawValue>(values: &[Q]) -> Q {
@@ -209,7 +201,25 @@ where
(sum / count).into()
}
quantity_fn!(median, values, statistical::median(&values));
pub fn median<Q, P>(values: impl IntoIterator<Item = Q>) -> Q
where
Q: Copy + PartialOrd + Add<Output = Q> + Div<Ratio, Output = P>,
P: Into<Q>,
{
let mut values = values.into_iter().collect::<Vec<_>>();
values.sort_by(|a, b| a.partial_cmp(b).expect("No NaN values"));
let len = values.len();
if len % 2 == 0 {
let mid = len / 2;
let a = &values[mid - 1];
let b = &values[mid];
((*a + *b) / Ratio::new::<ratio>(2.)).into()
} else {
values[len / 2]
}
}
quantity_fn!(standard_deviation, values, {
let mean_value = statistical::mean(&values);
statistical::standard_deviation(&values, Some(mean_value))
@@ -326,7 +336,10 @@ fn statistics() {
mean(values.iter().copied()).format(TimeUnit::Second),
"2.000 s"
);
assert_eq!(median(&values).format(TimeUnit::Second), "2.000 s");
assert_eq!(
median(values.iter().copied()).format(TimeUnit::Second),
"2.000 s"
);
assert_eq!(min(&values).format(TimeUnit::Second), "1.000 s");
assert_eq!(max(&values).format(TimeUnit::Second), "3.000 s");
assert_eq!(