From b6a7be8a962d25c93fa61e5c8d7a4508a909666c Mon Sep 17 00:00:00 2001 From: not-matthias Date: Thu, 26 Jun 2025 15:43:20 +0200 Subject: [PATCH] fix: stdev calculation for less than 2 runs --- crates/cargo-codspeed/src/walltime_results.rs | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/cargo-codspeed/src/walltime_results.rs b/crates/cargo-codspeed/src/walltime_results.rs index ef995aa6..2ce30087 100644 --- a/crates/cargo-codspeed/src/walltime_results.rs +++ b/crates/cargo-codspeed/src/walltime_results.rs @@ -59,7 +59,14 @@ impl From for WalltimeBenchmark { let total_time = times_ns.iter().sum::() / 1_000_000_000.0; let mean_ns = data.mean().unwrap(); - let stdev_ns = data.std_dev().unwrap(); + + let stdev_ns = if data.len() < 2 { + // std_dev() returns f64::NAN if data has less than two entries, so we have to + // manually handle this case. + 0.0 + } else { + data.std_dev().unwrap() + }; let q1_ns = data.quantile(0.25); let median_ns = data.median(); @@ -152,3 +159,28 @@ impl WalltimeResults { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_single_benchmark() { + let metadata = BenchmarkMetadata { + name: "benchmark".to_string(), + uri: "test::benchmark".to_string(), + }; + let raw_bench = RawWallTimeData { + metadata, + iter_per_round: 1, + max_time_ns: None, + times_ns: vec![42], + }; + + let benchmark: WalltimeBenchmark = raw_bench.into(); + assert_eq!(benchmark.stats.stdev_ns, 0.); + assert_eq!(benchmark.stats.min_ns, 42.); + assert_eq!(benchmark.stats.max_ns, 42.); + assert_eq!(benchmark.stats.mean_ns, 42.); + } +}