use std::collections::BTreeMap;
#[derive(Clone, Debug, PartialEq)]
pub struct SubMsStageSummary {
pub name: String,
pub count: usize,
pub p50_ns: u64,
pub p99_ns: u64,
pub p999_ns: u64,
pub max_ns: u64,
pub mean_ns: u64,
pub stddev_ns: u64,
pub cdf_buckets_ns: Vec<u64>,
pub jitter_score: f64,
pub samples_ns: Option<Vec<u64>>,
}
#[derive(Clone, Debug)]
pub struct SubMsBenchSummary {
pub workload: String,
pub lang: String,
pub timestamp: String,
pub cpu_core: Option<u32>,
pub cpu_affinity: Option<String>,
pub inputs: BTreeMap<String, String>,
pub meta: BTreeMap<String, String>,
pub stages: Vec<SubMsStageSummary>,
}
impl SubMsBenchSummary {
pub fn stage(&self, name: &str) -> Option<&SubMsStageSummary> {
self.stages.iter().find(|s| s.name == name)
}
}
#[derive(Clone, Debug)]
pub struct SubMsBenchSweep {
pub workload: String,
pub lang: String,
pub varied_input_key: Option<String>,
pub runs: Vec<SubMsBenchSummary>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct SubMsMetricDiff {
pub metric: String,
pub baseline_ns: u64,
pub candidate_ns: u64,
pub delta_ns: i64,
pub delta_pct: f64,
}
#[derive(Clone, Debug)]
pub struct SubMsStageDiff {
pub stage: String,
pub metrics: Vec<SubMsMetricDiff>,
pub worst_regression_pct: f64,
}
#[derive(Clone, Debug)]
pub struct SubMsBenchDiff {
pub baseline_workload: String,
pub candidate_workload: String,
pub lang: String,
pub stages: Vec<SubMsStageDiff>,
pub baseline_only_stages: Vec<String>,
pub candidate_only_stages: Vec<String>,
pub regression_threshold_pct: f64,
}
impl SubMsBenchDiff {
pub fn has_regression(&self) -> bool {
self.stages
.iter()
.any(|s| s.worst_regression_pct > self.regression_threshold_pct)
}
pub fn worst_stage(&self) -> Option<&SubMsStageDiff> {
self.stages.iter().max_by(|a, b| {
a.worst_regression_pct
.partial_cmp(&b.worst_regression_pct)
.unwrap_or(std::cmp::Ordering::Equal)
})
}
}