Represent memory usage as f64 as well

This commit is contained in:
David Peter authored and David Peter committed 2026-10-05 16:00:08 +02:00
1 parent 27ad0fb65e
commit 6b4e9eb5c2
8 files changed
+93 -79

No files matched your search

Generated
+1 -12
View File
@@ -515,7 +515,7 @@ dependencies = [
"num-complex", "num-complex",
"num-integer", "num-integer",
"num-iter", "num-iter",
"num-rational 0.2.4", "num-rational",
"num-traits", "num-traits",
] ]
@@ -572,16 +572,6 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@@ -1041,7 +1031,6 @@ version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffd36e5350a65d112584053ee91843955826bf9e56ec0d1351214e01f6d7cd9c" checksum = "ffd36e5350a65d112584053ee91843955826bf9e56ec0d1351214e01f6d7cd9c"
dependencies = [ dependencies = [
"num-rational 0.4.2",
"num-traits", "num-traits",
"typenum", "typenum",
] ]
-1
View File
@@ -32,7 +32,6 @@ uom = { version = "0.36.0", default-features = false, features = [
"std", "std",
"si", "si",
"f64", "f64",
"u64",
] } ] }
[target.'cfg(not(windows))'.dependencies] [target.'cfg(not(windows))'.dependencies]
+2 -2
View File
@@ -9,7 +9,7 @@ use crate::options::{
CmdFailureAction, CommandInputPolicy, CommandOutputPolicy, Options, OutputStyleOption, Shell, CmdFailureAction, CommandInputPolicy, CommandOutputPolicy, Options, OutputStyleOption, Shell,
}; };
use crate::output::progress_bar::get_progress_bar; use crate::output::progress_bar::get_progress_bar;
use crate::quantity::{byte, second, Information, Time, TimeQuantity}; use crate::quantity::{second, Information, InformationQuantity, Time, TimeQuantity};
use crate::timer::execute_and_measure; use crate::timer::execute_and_measure;
use crate::util::randomized_environment_offset; use crate::util::randomized_environment_offset;
@@ -348,7 +348,7 @@ impl Executor for MockExecutor {
time_wall_clock: Self::extract_time(command.get_command_line()), time_wall_clock: Self::extract_time(command.get_command_line()),
time_user: Time::zero(), time_user: Time::zero(),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(0), peak_memory_usage: Information::zero(),
exit_status, exit_status,
}) })
} }
+10 -14
View File
@@ -2,10 +2,9 @@ use std::process::ExitStatus;
use serde::Serialize; use serde::Serialize;
use crate::outlier_detection::modified_zscores;
use crate::quantity::{ use crate::quantity::{
max, mean, median, min, second, serialize_information, serialize_time, standard_deviation, max, mean, median, min, modified_zscores, serialize_information, serialize_time,
Information, Time, TimeQuantity, standard_deviation, Information, Time,
}; };
use crate::util::exit_code::extract_exit_code; use crate::util::exit_code::extract_exit_code;
@@ -103,6 +102,11 @@ impl Measurements {
max(&self.wall_clock_times()) max(&self.wall_clock_times())
} }
/// Compute modified Z-scores for the wall clock times
pub fn modified_zscores(&self) -> Vec<f64> {
modified_zscores(&self.wall_clock_times())
}
/// The average user time /// The average user time
pub fn time_user_mean(&self) -> Time { pub fn time_user_mean(&self) -> Time {
mean( mean(
@@ -126,19 +130,11 @@ impl Measurements {
} }
pub fn peak_memory_usage_mean(&self) -> Information { pub fn peak_memory_usage_mean(&self) -> Information {
self.measurements mean(
.iter()
.map(|m| m.peak_memory_usage)
.max() // TODO: should be mean: do we need InformationF64?
.unwrap_or_default()
}
pub fn modified_zscores(&self) -> Vec<f64> {
modified_zscores(
&self &self
.wall_clock_times() .measurements
.iter() .iter()
.map(|t| t.value_in(second)) // TODO .map(|m| m.peak_memory_usage)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
) )
} }
+6 -6
View File
@@ -85,21 +85,21 @@ fn test_csv() {
time_wall_clock: Time::new::<second>(7.0), time_wall_clock: Time::new::<second>(7.0),
time_user: Time::new::<second>(7.0), time_user: Time::new::<second>(7.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(8.0), time_wall_clock: Time::new::<second>(8.0),
time_user: Time::new::<second>(8.0), time_user: Time::new::<second>(8.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(12.0), time_wall_clock: Time::new::<second>(12.0),
time_user: Time::new::<second>(12.0), time_user: Time::new::<second>(12.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -129,21 +129,21 @@ fn test_csv() {
time_wall_clock: Time::new::<second>(17.0), time_wall_clock: Time::new::<second>(17.0),
time_user: Time::new::<second>(17.0), time_user: Time::new::<second>(17.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(18.0), time_wall_clock: Time::new::<second>(18.0),
time_user: Time::new::<second>(18.0), time_user: Time::new::<second>(18.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(19.0), time_wall_clock: Time::new::<second>(19.0),
time_user: Time::new::<second>(19.0), time_user: Time::new::<second>(19.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
+24 -24
View File
@@ -33,21 +33,21 @@ fn test_markup_export_auto_ms() {
time_wall_clock: Time::new::<second>(0.09), time_wall_clock: Time::new::<second>(0.09),
time_user: Time::new::<second>(0.09), time_user: Time::new::<second>(0.09),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.10), time_wall_clock: Time::new::<second>(0.10),
time_user: Time::new::<second>(0.10), time_user: Time::new::<second>(0.10),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.14), time_wall_clock: Time::new::<second>(0.14),
time_user: Time::new::<second>(0.14), time_user: Time::new::<second>(0.14),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -60,21 +60,21 @@ fn test_markup_export_auto_ms() {
time_wall_clock: Time::new::<second>(2.0), time_wall_clock: Time::new::<second>(2.0),
time_user: Time::new::<second>(2.0), time_user: Time::new::<second>(2.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(3.0), time_wall_clock: Time::new::<second>(3.0),
time_user: Time::new::<second>(3.0), time_user: Time::new::<second>(3.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(4.0), time_wall_clock: Time::new::<second>(4.0),
time_user: Time::new::<second>(4.0), time_user: Time::new::<second>(4.0),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -132,21 +132,21 @@ fn test_markup_export_auto_s() {
time_wall_clock: Time::new::<second>(2.1), time_wall_clock: Time::new::<second>(2.1),
time_user: Time::new::<second>(2.1), time_user: Time::new::<second>(2.1),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(2.2), time_wall_clock: Time::new::<second>(2.2),
time_user: Time::new::<second>(2.2), time_user: Time::new::<second>(2.2),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(2.3), time_wall_clock: Time::new::<second>(2.3),
time_user: Time::new::<second>(2.3), time_user: Time::new::<second>(2.3),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -159,21 +159,21 @@ fn test_markup_export_auto_s() {
time_wall_clock: Time::new::<second>(0.1), time_wall_clock: Time::new::<second>(0.1),
time_user: Time::new::<second>(0.1), time_user: Time::new::<second>(0.1),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.2), time_wall_clock: Time::new::<second>(0.2),
time_user: Time::new::<second>(0.2), time_user: Time::new::<second>(0.2),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.3), time_wall_clock: Time::new::<second>(0.3),
time_user: Time::new::<second>(0.3), time_user: Time::new::<second>(0.3),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -231,21 +231,21 @@ fn test_markup_export_manual_ms() {
time_wall_clock: Time::new::<second>(2.1), time_wall_clock: Time::new::<second>(2.1),
time_user: Time::new::<second>(2.1), time_user: Time::new::<second>(2.1),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(2.2), time_wall_clock: Time::new::<second>(2.2),
time_user: Time::new::<second>(2.2), time_user: Time::new::<second>(2.2),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(2.3), time_wall_clock: Time::new::<second>(2.3),
time_user: Time::new::<second>(2.3), time_user: Time::new::<second>(2.3),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -258,21 +258,21 @@ fn test_markup_export_manual_ms() {
time_wall_clock: Time::new::<second>(0.1), time_wall_clock: Time::new::<second>(0.1),
time_user: Time::new::<second>(0.1), time_user: Time::new::<second>(0.1),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.2), time_wall_clock: Time::new::<second>(0.2),
time_user: Time::new::<second>(0.2), time_user: Time::new::<second>(0.2),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.3), time_wall_clock: Time::new::<second>(0.3),
time_user: Time::new::<second>(0.3), time_user: Time::new::<second>(0.3),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -329,21 +329,21 @@ fn test_markup_export_manual_s() {
time_wall_clock: Time::new::<second>(2.01), time_wall_clock: Time::new::<second>(2.01),
time_user: Time::new::<second>(2.01), time_user: Time::new::<second>(2.01),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(2.02), time_wall_clock: Time::new::<second>(2.02),
time_user: Time::new::<second>(2.02), time_user: Time::new::<second>(2.02),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(2.03), time_wall_clock: Time::new::<second>(2.03),
time_user: Time::new::<second>(2.03), time_user: Time::new::<second>(2.03),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
@@ -356,21 +356,21 @@ fn test_markup_export_manual_s() {
time_wall_clock: Time::new::<second>(0.11), time_wall_clock: Time::new::<second>(0.11),
time_user: Time::new::<second>(0.11), time_user: Time::new::<second>(0.11),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.12), time_wall_clock: Time::new::<second>(0.12),
time_user: Time::new::<second>(0.12), time_user: Time::new::<second>(0.12),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
Measurement { Measurement {
time_wall_clock: Time::new::<second>(0.13), time_wall_clock: Time::new::<second>(0.13),
time_user: Time::new::<second>(0.13), time_user: Time::new::<second>(0.13),
time_system: Time::zero(), time_system: Time::zero(),
peak_memory_usage: Information::new::<byte>(1024), peak_memory_usage: Information::new::<byte>(1024.),
exit_status: ExitStatus::default(), exit_status: ExitStatus::default(),
}, },
]), ]),
+45 -17
View File
@@ -9,9 +9,7 @@ pub use uom::si::information::{byte, kibibyte};
pub use uom::si::ratio::ratio; pub use uom::si::ratio::ratio;
pub use uom::si::time::{hour, microsecond, millisecond, minute, nanosecond, second}; pub use uom::si::time::{hour, microsecond, millisecond, minute, nanosecond, second};
pub use si::f64::Ratio; pub use si::f64::{Information, Ratio, Time};
pub use si::f64::Time;
pub use si::u64::Information;
pub use si::f64::{Information, Ratio, Time}; pub use si::f64::{Information, Ratio, Time};
pub use si::information::{byte, gibibyte, kibibyte, mebibyte, tebibyte}; pub use si::information::{byte, gibibyte, kibibyte, mebibyte, tebibyte};
@@ -92,29 +90,29 @@ pub const fn const_time_from_seconds(value: f64) -> Time {
pub trait InformationQuantity { pub trait InformationQuantity {
fn zero() -> Information { fn zero() -> Information {
Information::new::<byte>(0) Information::new::<byte>(0.)
} }
fn value_in<U>(&self, u: U) -> u64 fn value_in<U>(&self, u: U) -> f64
where where
U: si::information::Unit + Conversion<u64, T = uom::num_rational::Ratio<u64>>; U: si::information::Unit + Conversion<f64, T = f64>;
fn to_string<U>(&self, u: U) -> String fn to_string<U>(&self, u: U) -> String
where where
U: si::information::Unit + Conversion<u64, T = uom::num_rational::Ratio<u64>>; U: si::information::Unit + Conversion<f64, T = f64>;
} }
impl InformationQuantity for Information { impl InformationQuantity for Information {
fn value_in<U>(&self, _u: U) -> u64 fn value_in<U>(&self, _u: U) -> f64
where where
U: si::information::Unit + Conversion<u64, T = uom::num_rational::Ratio<u64>>, U: si::information::Unit + Conversion<f64, T = f64>,
{ {
self.get::<U>() self.get::<U>()
} }
fn to_string<U>(&self, u: U) -> String fn to_string<U>(&self, u: U) -> String
where where
U: si::information::Unit + Conversion<u64, T = uom::num_rational::Ratio<u64>>, U: si::information::Unit + Conversion<f64, T = f64>,
{ {
format!( format!(
"{}", "{}",
@@ -123,6 +121,31 @@ impl InformationQuantity for Information {
} }
} }
pub trait UnsafeRawValue {
fn unsafe_raw_value(&self) -> f64;
fn unsafe_from_raw_value(value: f64) -> Self;
}
impl UnsafeRawValue for Time {
fn unsafe_raw_value(&self) -> f64 {
self.value_in(second)
}
fn unsafe_from_raw_value(value: f64) -> Self {
Time::new::<second>(value)
}
}
impl UnsafeRawValue for Information {
fn unsafe_raw_value(&self) -> f64 {
self.value_in(byte)
}
fn unsafe_from_raw_value(value: f64) -> Self {
Information::new::<byte>(value)
}
}
pub fn serialize_time<S>(t: &Time, s: S) -> Result<S::Ok, S::Error> pub fn serialize_time<S>(t: &Time, s: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
@@ -145,11 +168,11 @@ where
macro_rules! quantity_fn { macro_rules! quantity_fn {
($name:ident, $unwrapped_values:ident, $body:expr) => { ($name:ident, $unwrapped_values:ident, $body:expr) => {
pub fn $name(values: &[Time]) -> Time { pub fn $name<Q: UnsafeRawValue>(values: &[Q]) -> Q {
let $unwrapped_values: Vec<_> = values.iter().map(|q| q.value_in(second)).collect(); let $unwrapped_values: Vec<_> = values.iter().map(|q| q.unsafe_raw_value()).collect();
let result_value = $body; let result_value = $body;
Time::new::<second>(result_value) Q::unsafe_from_raw_value(result_value)
} }
}; };
} }
@@ -163,6 +186,11 @@ quantity_fn!(standard_deviation, values, {
statistical::standard_deviation(&values, Some(mean_value)) statistical::standard_deviation(&values, Some(mean_value))
}); });
pub fn modified_zscores<Q: UnsafeRawValue>(values: &[Q]) -> Vec<f64> {
let values: Vec<_> = values.iter().map(|q| q.unsafe_raw_value()).collect();
crate::outlier_detection::modified_zscores(&values)
}
#[test] #[test]
fn test_time() { fn test_time() {
let time = Time::new::<millisecond>(123.4); let time = Time::new::<millisecond>(123.4);
@@ -177,11 +205,11 @@ fn test_time() {
#[test] #[test]
fn test_information() { fn test_information() {
let information = Information::new::<kibibyte>(8); let information = Information::new::<kibibyte>(8.);
assert_eq!(information.value_in(byte), 8192); assert_eq!(information.value_in(byte), 8192.);
let information_kib = information.value_in(kibibyte); let information_kib = information.value_in(kibibyte);
assert_eq!(information_kib, 8); assert_eq!(information_kib, 8.);
} }
#[test] #[test]
@@ -191,7 +219,7 @@ fn test_format() {
assert_eq!(time.format_auto(Some(TimeUnit::MilliSecond)), "123.4 ms"); assert_eq!(time.format_auto(Some(TimeUnit::MilliSecond)), "123.4 ms");
assert_eq!(time.format_auto(Some(TimeUnit::MicroSecond)), "123400.0 µs"); assert_eq!(time.format_auto(Some(TimeUnit::MicroSecond)), "123400.0 µs");
let peak_memory_usage = Information::new::<kibibyte>(8); let peak_memory_usage = Information::new::<kibibyte>(8.);
assert_eq!(peak_memory_usage.to_string(byte), "8192 B"); assert_eq!(peak_memory_usage.to_string(byte), "8192 B");
assert_eq!(peak_memory_usage.to_string(kibibyte), "8 KiB"); assert_eq!(peak_memory_usage.to_string(kibibyte), "8 KiB");
} }
+5 -3
View File
@@ -1,6 +1,5 @@
#![cfg(not(windows))] #![cfg(not(windows))]
use std::convert::TryFrom;
use std::io; use std::io;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::os::unix::process::ExitStatusExt; use std::os::unix::process::ExitStatusExt;
@@ -47,9 +46,12 @@ fn wait4(mut child: Child) -> io::Result<(ExitStatus, ResourceUsage)> {
let memory_usage_byte = if cfg!(target_os = "macos") || cfg!(target_os = "ios") { let memory_usage_byte = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
// Linux and *BSD return the value in KibiBytes, Darwin flavors in bytes // Linux and *BSD return the value in KibiBytes, Darwin flavors in bytes
Information::new::<byte>(u64::try_from(rusage.ru_maxrss).unwrap_or(0)) // A f64 can represent integers up to 2^53 exactly, so we can represent
// all values up to 2^53 bytes = 8 PiB exactly. Beyond that, our precision
// is larger than 1 byte, but that's considered acceptable.
Information::new::<byte>(rusage.ru_maxrss as f64)
} else { } else {
Information::new::<kibibyte>(u64::try_from(rusage.ru_maxrss).unwrap_or(0)) Information::new::<kibibyte>(rusage.ru_maxrss as f64)
}; };
Ok(( Ok((