Skip to main content

fluxbench_cli/executor/
statistics.rs

1//! Statistics Computation
2//!
3//! Parallel computation of summary statistics for benchmark results.
4//!
5//! Uses Rayon to parallelize statistics computation across benchmarks.
6//! Each benchmark's samples are processed independently to compute:
7//! - Central tendency (mean, median)
8//! - Dispersion (std dev, min, max)
9//! - Percentiles (p50, p90, p95, p99, p999)
10//! - Outlier detection via IQR method
11
12use super::execution::{BenchExecutionResult, ExecutionConfig};
13use fluxbench_stats::{OutlierMethod, SummaryStatistics, compute_summary};
14use rayon::prelude::*;
15
16/// Compute statistics for benchmark results (parallelized with Rayon)
17///
18/// Uses Rayon for parallel computation of summary statistics across all benchmarks.
19/// Each benchmark's samples are independently processed, making this highly parallelizable.
20///
21/// # Arguments
22/// * `results` - Benchmark execution results containing samples
23/// * `_config` - Execution configuration. Currently unused but reserved for future
24///   extensions such as configurable outlier detection methods, custom percentile
25///   thresholds, or alternative statistical algorithms.
26///
27/// # Returns
28/// Vector of (benchmark_id, optional statistics) pairs. Returns `None` for benchmarks
29/// with no samples (e.g., crashed or skipped benchmarks).
30pub fn compute_statistics(
31    results: &[BenchExecutionResult],
32    _config: &ExecutionConfig,
33) -> Vec<(String, Option<SummaryStatistics>)> {
34    results
35        .par_iter() // Parallel iteration
36        .map(|r| {
37            if r.samples.is_empty() {
38                (r.benchmark_id.clone(), None)
39            } else {
40                let stats = compute_summary(&r.samples, OutlierMethod::Iqr { k: 3 }); // k=3 means 1.5*IQR
41                (r.benchmark_id.clone(), Some(stats))
42            }
43        })
44        .collect()
45}