Store typed Measurements in BenchmarkResult

This commit is contained in:
David Peter committed 2026-10-05 12:46:10 +02:00
1 parent 05de077d8e
commit b23372c5e2
7 files changed
+432 -257

No files matched your search

+41 -19
View File
@@ -2,6 +2,7 @@ use std::cmp::Ordering;
use super::benchmark_result::BenchmarkResult;
use crate::options::SortOrder;
use crate::quantity::second;
#[derive(Debug)]
pub struct BenchmarkResultWithRelativeSpeed<'a> {
@@ -14,7 +15,10 @@ pub struct BenchmarkResultWithRelativeSpeed<'a> {
}
pub fn compare_mean_time(l: &BenchmarkResult, r: &BenchmarkResult) -> Ordering {
l.mean.partial_cmp(&r.mean).unwrap_or(Ordering::Equal)
l.mean_wall_clock_time()
.get::<second>()
.partial_cmp(&r.mean_wall_clock_time().get::<second>())
.unwrap_or(Ordering::Equal)
}
pub fn fastest_of(results: &[BenchmarkResult]) -> &BenchmarkResult {
@@ -35,7 +39,7 @@ fn compute_relative_speeds<'a>(
let is_reference = result == reference;
let relative_ordering = compare_mean_time(result, reference);
if result.mean == 0.0 {
if result.mean_wall_clock_time().get::<second>() == 0.0 {
return BenchmarkResultWithRelativeSpeed {
result,
relative_speed: if is_reference { 1.0 } else { f64::INFINITY },
@@ -46,18 +50,34 @@ fn compute_relative_speeds<'a>(
}
let ratio = match relative_ordering {
Ordering::Less => reference.mean / result.mean,
Ordering::Less => {
reference.mean_wall_clock_time().get::<second>()
/ result.mean_wall_clock_time().get::<second>()
}
Ordering::Equal => 1.0,
Ordering::Greater => result.mean / reference.mean,
Ordering::Greater => {
result.mean_wall_clock_time().get::<second>()
/ reference.mean_wall_clock_time().get::<second>()
}
};
// https://en.wikipedia.org/wiki/Propagation_of_uncertainty#Example_formulas
// Covariance assumed to be 0, i.e. variables are assumed to be independent
let ratio_stddev = match (result.stddev, reference.stddev) {
let ratio_stddev = match (
result
.measurements
.stddev()
.map(|time| time.get::<second>()),
reference
.measurements
.stddev()
.map(|time| time.get::<second>()),
) {
(Some(result_stddev), Some(fastest_stddev)) => Some(
ratio
* ((result_stddev / result.mean).powi(2)
+ (fastest_stddev / reference.mean).powi(2))
* ((result_stddev / result.mean_wall_clock_time().get::<second>()).powi(2)
+ (fastest_stddev / reference.mean_wall_clock_time().get::<second>())
.powi(2))
.sqrt(),
),
_ => None,
@@ -88,7 +108,9 @@ pub fn compute_with_check_from_reference<'a>(
reference: &'a BenchmarkResult,
sort_order: SortOrder,
) -> Option<Vec<BenchmarkResultWithRelativeSpeed<'a>>> {
if fastest_of(results).mean == 0.0 || reference.mean == 0.0 {
if fastest_of(results).mean_wall_clock_time().get::<second>() == 0.0
|| reference.mean_wall_clock_time().get::<second>() == 0.0
{
return None;
}
@@ -101,7 +123,7 @@ pub fn compute_with_check(
) -> Option<Vec<BenchmarkResultWithRelativeSpeed<'_>>> {
let fastest = fastest_of(results);
if fastest.mean == 0.0 {
if fastest.mean_wall_clock_time().get::<second>() == 0.0 {
return None;
}
@@ -122,19 +144,19 @@ pub fn compute(
fn create_result(name: &str, mean: f64) -> BenchmarkResult {
use std::collections::BTreeMap;
use crate::benchmark::measurement::{Measurement, Measurements};
use crate::quantity::{second, Time};
BenchmarkResult {
command: name.into(),
command_with_unused_parameters: name.into(),
mean,
stddev: Some(1.0),
median: mean,
user: mean,
system: 0.0,
min: mean,
max: mean,
times: None,
memory_usage_byte: None,
exit_codes: Vec::new(),
measurements: Measurements {
measurements: vec![Measurement {
time_wall_clock: Time::new::<second>(mean),
time_user: Time::new::<second>(mean),
..Default::default()
}],
},
parameters: BTreeMap::new(),
}
}