diff --git a/src/benchmark/benchmark_result.rs b/src/benchmark/benchmark_result.rs index f990c94..27ff543 100644 --- a/src/benchmark/benchmark_result.rs +++ b/src/benchmark/benchmark_result.rs @@ -2,7 +2,8 @@ use std::collections::BTreeMap; use serde::Serialize; -use crate::benchmark::{measurement::Measurements, quantity::Time}; +use crate::benchmark::measurement::Measurements; +use crate::quantity::Time; /// Parameter value and whether it was used in the command line template #[derive(Debug, Default, Clone, Serialize, PartialEq)] diff --git a/src/benchmark/executor.rs b/src/benchmark/executor.rs index a6e8150..f26a98d 100644 --- a/src/benchmark/executor.rs +++ b/src/benchmark/executor.rs @@ -4,14 +4,14 @@ use std::process::ExitStatus; use crate::benchmark::measurement::Measurement; use crate::benchmark::measurement::Measurements; -use crate::benchmark::quantity::Information; -use crate::benchmark::quantity::InformationQuantity; -use crate::benchmark::quantity::{Time, TimeQuantity}; use crate::command::Command; use crate::options::{ CmdFailureAction, CommandInputPolicy, CommandOutputPolicy, Options, OutputStyleOption, Shell, }; use crate::output::progress_bar::get_progress_bar; +use crate::quantity::Information; +use crate::quantity::InformationQuantity; +use crate::quantity::{Time, TimeQuantity}; use crate::timer::execute_and_measure; use crate::util::randomized_environment_offset; diff --git a/src/benchmark/measurement.rs b/src/benchmark/measurement.rs index 7895b73..d80e940 100644 --- a/src/benchmark/measurement.rs +++ b/src/benchmark/measurement.rs @@ -2,11 +2,11 @@ use std::process::ExitStatus; use serde::Serialize; -use crate::benchmark::quantity::{ +use crate::outlier_detection::modified_zscores; +use crate::quantity::{ max, mean, median, min, second, serialize_information, serialize_time, standard_deviation, Information, Time, TimeQuantity, }; -use crate::outlier_detection::modified_zscores; use crate::util::exit_code::extract_exit_code; fn serialize_exit_status(exit_status: &ExitStatus, serializer: S) -> Result diff --git a/src/benchmark/mod.rs b/src/benchmark/mod.rs index ddbba81..3ccb55f 100644 --- a/src/benchmark/mod.rs +++ b/src/benchmark/mod.rs @@ -1,7 +1,6 @@ pub mod benchmark_result; pub mod executor; pub mod measurement; -pub mod quantity; pub mod relative_speed; pub mod scheduler; @@ -12,7 +11,6 @@ use std::time::Instant; use crate::benchmark::benchmark_result::Parameter; use crate::benchmark::executor::BenchmarkIteration; use crate::benchmark::measurement::{Measurement, Measurements}; -use crate::benchmark::quantity::{const_time_from_seconds, Time, TimeQuantity}; use crate::command::Command; use crate::options::{ CmdFailureAction, CommandOutputPolicy, ExecutorKind, Options, OutputStyleOption, @@ -25,6 +23,7 @@ use crate::output::progress_bar::{ }; use crate::output::warnings::{OutlierWarningOptions, Warnings}; use crate::parameter::ParameterNameAndValue; +use crate::quantity::{self, const_time_from_seconds, Time, TimeQuantity}; use benchmark_result::BenchmarkResult; use anyhow::{anyhow, Result}; diff --git a/src/benchmark/quantity.rs b/src/benchmark/quantity.rs deleted file mode 100644 index 2b7063d..0000000 --- a/src/benchmark/quantity.rs +++ /dev/null @@ -1,198 +0,0 @@ -use core::f64; -use std::marker::PhantomData; - -use serde::ser::SerializeStruct; -use serde::Serializer; -use uom::{si, Conversion}; - -pub use uom::si::information::{byte, kibibyte}; -pub use uom::si::ratio::ratio; -pub use uom::si::time::{microsecond, millisecond, nanosecond, second}; - -pub use si::f64::Ratio; -pub use si::f64::Time; -pub use si::u64::Information; - -pub trait TimeQuantity { - fn zero() -> Time { - Time::new::(0.0) - } - - fn from_seconds(value: f64) -> Time { - Time::new::(value) - } - - fn from_milliseconds(value: f64) -> Time { - Time::new::(value) - } - - fn from_microseconds(value: f64) -> Time { - Time::new::(value) - } - - fn from_nanoseconds(value: f64) -> Time { - Time::new::(value) - } - - // fn square(&self) -> Time; - - fn value_in(&self) -> f64 - where - U: si::time::Unit + Conversion; - - fn to_string(&self, u: U) -> String - where - U: si::time::Unit + Conversion; -} - -impl TimeQuantity for Time { - fn value_in(&self) -> f64 - where - U: si::time::Unit + Conversion, - { - self.get::() - } - - fn to_string(&self, u: U) -> String - where - U: si::time::Unit + Conversion, - { - format!( - "{:.3}", - self.into_format_args(u, uom::fmt::DisplayStyle::Abbreviation) - ) - } -} - -pub const fn const_time_from_seconds(value: f64) -> Time { - // Quantity::new in uom is not yet const: https://docs.rs/uom/0.36.0/uom/si/struct.Quantity.html - Time { - dimension: PhantomData, - units: PhantomData, - value, - } -} - -pub trait InformationQuantity { - fn zero() -> Information { - Information::new::(0) - } - - fn from_bytes(value: u64) -> Information { - Information::new::(value) - } - - fn from_kibibytes(value: u64) -> Information { - Information::new::(value) - } - - fn value_in(&self) -> u64 - where - U: si::information::Unit + Conversion>; - - fn to_string(&self, u: U) -> String - where - U: si::information::Unit + Conversion>; -} - -impl InformationQuantity for Information { - fn value_in(&self) -> u64 - where - U: si::information::Unit + Conversion>, - { - self.get::() - } - - fn to_string(&self, u: U) -> String - where - U: si::information::Unit + Conversion>, - { - format!( - "{}", - self.into_format_args(u, uom::fmt::DisplayStyle::Abbreviation) - ) - } -} - -pub fn serialize_time(t: &Time, s: S) -> Result -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(i: &Information, s: S) -> Result -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(values: &[Time]) -> Time { - let $unwrapped_values: Vec<_> = values.iter().map(|q| q.value_in::()).collect(); - let result_value = $body; - - Time::new::(result_value) - } - }; -} - -quantity_fn!(mean, values, statistical::mean(&values)); -quantity_fn!(median, values, statistical::median(&values)); -quantity_fn!(min, values, crate::util::min_max::min(&values)); -quantity_fn!(max, values, crate::util::min_max::max(&values)); -quantity_fn!(standard_deviation, values, { - let mean_value = statistical::mean(&values); - statistical::standard_deviation(&values, Some(mean_value)) -}); - -#[test] -fn test_time() { - let time = Time::from_milliseconds(123.4); - assert_eq!(time.value_in::(), 123.4); - - let time_s = time.value_in::(); - approx::assert_relative_eq!(time_s, 0.1234); - - let time_us = time.value_in::(); - approx::assert_relative_eq!(time_us, 123400.0); -} - -#[test] -fn test_information() { - let information = Information::from_kibibytes(8); - assert_eq!(information.value_in::(), 8192); - - let information_kib = information.value_in::(); - assert_eq!(information_kib, 8); -} - -#[test] -fn test_format() { - let time = Time::from_milliseconds(123.4); - assert_eq!(time.to_string(second), "0.123 s"); - assert_eq!(time.to_string(millisecond), "123.400 ms"); - assert_eq!(time.to_string(microsecond), "123400.000 µs"); - - let peak_memory_usage = Information::from_kibibytes(8); - assert_eq!(peak_memory_usage.to_string(byte), "8192 B"); - assert_eq!(peak_memory_usage.to_string(kibibyte), "8 KiB"); -} - -#[test] -fn test_mean() { - let values = vec![ - Time::from_milliseconds(123.4), - Time::from_milliseconds(234.5), - ]; - let result = mean(&values); - assert_eq!(result.to_string(millisecond), "178.950 ms"); -} diff --git a/src/benchmark/relative_speed.rs b/src/benchmark/relative_speed.rs index d6c0676..fe871e1 100644 --- a/src/benchmark/relative_speed.rs +++ b/src/benchmark/relative_speed.rs @@ -2,8 +2,8 @@ use std::cmp::Ordering; use super::benchmark_result::BenchmarkResult; use crate::{ - benchmark::quantity::{self, Ratio, Time, TimeQuantity}, options::SortOrder, + quantity::{self, Ratio, Time, TimeQuantity}, }; #[derive(Debug)] diff --git a/src/export/csv.rs b/src/export/csv.rs index 3ab84a0..8fb49c5 100644 --- a/src/export/csv.rs +++ b/src/export/csv.rs @@ -4,9 +4,9 @@ use csv::WriterBuilder; use super::Exporter; use crate::benchmark::benchmark_result::BenchmarkResult; -use crate::benchmark::quantity::{second, TimeQuantity}; use crate::options::SortOrder; -use crate::quantity::{FormatQuantity, TimeUnit}; +use crate::quantity::{second, TimeQuantity}; +use crate::util::units::Unit; use anyhow::Result; @@ -69,7 +69,7 @@ impl Exporter for CsvExporter { fn test_csv() { use crate::benchmark::benchmark_result::Parameter; use crate::benchmark::measurement::{Measurement, Measurements}; - use crate::benchmark::quantity::{Information, InformationQuantity, Time, TimeQuantity}; + use crate::quantity::{Information, InformationQuantity, Time, TimeQuantity}; use std::collections::BTreeMap; use std::process::ExitStatus; diff --git a/src/export/tests.rs b/src/export/tests.rs index 4355c0a..72358e8 100644 --- a/src/export/tests.rs +++ b/src/export/tests.rs @@ -1,10 +1,10 @@ use super::Exporter; use crate::benchmark::benchmark_result::BenchmarkResult; use crate::benchmark::measurement::{Measurement, Measurements}; -use crate::benchmark::quantity::{Information, InformationQuantity, Time, TimeQuantity}; use crate::export::asciidoc::AsciidocExporter; use crate::export::orgmode::OrgmodeExporter; -use crate::quantity::{byte, second, Information, Time, TimeUnit, Zero}; +use crate::quantity::{Information, InformationQuantity, Time, TimeQuantity}; +use crate::util::units::Unit; use crate::{export::markdown::MarkdownExporter, options::SortOrder}; use std::collections::BTreeMap; use std::process::ExitStatus; diff --git a/src/options.rs b/src/options.rs index c9e5659..0c77a3e 100644 --- a/src/options.rs +++ b/src/options.rs @@ -7,9 +7,9 @@ use std::{cmp, env, fmt, io}; use anyhow::{bail, ensure}; use clap::ArgMatches; -use crate::benchmark::quantity::{Time, TimeQuantity}; use crate::command::Commands; use crate::error::OptionsError; +use crate::quantity::{Time, TimeQuantity}; use crate::util::units::Unit; use anyhow::Result; diff --git a/src/output/warnings.rs b/src/output/warnings.rs index 93f68d9..bcbfcd3 100644 --- a/src/output/warnings.rs +++ b/src/output/warnings.rs @@ -1,8 +1,8 @@ use std::fmt; -use crate::benchmark::quantity::{millisecond, Time, TimeQuantity}; use crate::benchmark::MIN_EXECUTION_TIME; use crate::output::format::format_duration; +use crate::quantity::{millisecond, Time, TimeQuantity}; pub struct OutlierWarningOptions { pub warmup_in_use: bool, diff --git a/src/timer/unix_timer.rs b/src/timer/unix_timer.rs index 524a975..2978248 100644 --- a/src/timer/unix_timer.rs +++ b/src/timer/unix_timer.rs @@ -8,7 +8,7 @@ use std::process::{Child, ExitStatus}; use anyhow::Result; -use crate::benchmark::quantity::{Information, InformationQuantity, Time, TimeQuantity}; +use crate::quantity::{Information, InformationQuantity, Time, TimeQuantity}; #[derive(Debug, Copy, Clone)] struct ResourceUsage { diff --git a/src/timer/wall_clock_timer.rs b/src/timer/wall_clock_timer.rs index 2a2c460..68a543a 100644 --- a/src/timer/wall_clock_timer.rs +++ b/src/timer/wall_clock_timer.rs @@ -1,6 +1,6 @@ use std::time::Instant; -use crate::benchmark::quantity::{Time, TimeQuantity}; +use crate::quantity::{Time, TimeQuantity}; pub struct WallClockTimer { start: Instant, diff --git a/src/timer/windows_timer.rs b/src/timer/windows_timer.rs index 0d14d40..b7e61e3 100644 --- a/src/timer/windows_timer.rs +++ b/src/timer/windows_timer.rs @@ -30,7 +30,7 @@ use windows_sys::{ }, }; -use crate::benchmark::quantity::{Information, InformationQuantity, Time, TimeQuantity}; +use crate::quantity::{Information, InformationQuantity, Time, TimeQuantity}; #[cfg(not(feature = "windows_process_extensions_main_thread_handle"))] #[allow(non_upper_case_globals)]