Skip to main content

benchmark_rs/
run_summary.rs

1use chrono::{DateTime, Utc};
2use num_traits::cast::ToPrimitive;
3use serde::{Deserialize, Serialize};
4
5/// Result of single workload point run
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct RunSummary {
8    name: String,
9    ramp_up: usize,
10    repeat: usize,
11    min_nanos: u64,
12    min_sec: f64,
13    min_str: String,
14    max_nanos: u64,
15    max_sec: f64,
16    max_str: String,
17    median_nanos: u64,
18    median_sec: f64,
19    median_str: String,
20    std_dev: Option<f64>,
21    std_dev_sec: Option<f64>,
22    std_dev_str: String,
23}
24
25impl RunSummary {
26    pub(crate) fn new(
27        name: String,
28        ramp_up: usize,
29        repeat: usize,
30        min: u64,
31        max: u64,
32        median: u64,
33        std_dev: Option<f64>,
34    ) -> RunSummary {
35        RunSummary {
36            name,
37            ramp_up,
38            repeat,
39            min_nanos: min,
40            min_sec: min as f64 / 1e9,
41            min_str: Self::format_elapsed_nanos(min),
42            max_nanos: max,
43            max_sec: max as f64 / 1e9,
44            max_str: Self::format_elapsed_nanos(max),
45            median_nanos: median,
46            median_sec: median as f64 / 1e9,
47            median_str: Self::format_elapsed_nanos(median),
48            std_dev,
49            std_dev_sec: std_dev.map(|x| x / 1e9),
50            std_dev_str: Self::format_std_dev_nanos(std_dev),
51        }
52    }
53
54    pub fn name(&self) -> &String {
55        &self.name
56    }
57
58    pub fn min_nanos(&self) -> u64 {
59        self.min_nanos
60    }
61
62    pub fn max_nanos(&self) -> u64 {
63        self.max_nanos
64    }
65
66    pub fn median_nanos(&self) -> u64 {
67        self.median_nanos
68    }
69
70    pub fn std_dev(&self) -> Option<f64> {
71        self.std_dev
72    }
73
74    fn format_elapsed_nanos(t: u64) -> String {
75        let (secs, nsecs) = ((t / 1_000_000_000) as i64, (t % 1_000_000_000) as u32);
76        let datetime = DateTime::<Utc>::from_timestamp(secs, nsecs).unwrap();
77        datetime.format("%H:%M:%S.%3f").to_string()
78    }
79
80    fn format_std_dev_nanos(std_dev_opt: Option<f64>) -> String {
81        match std_dev_opt {
82            None => "null".to_string(),
83            Some(std_dev) => match std_dev.to_i64() {
84                None => "null".to_string(),
85                Some(t) => {
86                    let (secs, nsecs) = ((t / 1_000_000_000), (t % 1_000_000_000) as u32);
87                    let datetime = DateTime::<Utc>::from_timestamp(secs, nsecs).unwrap();
88                    datetime.format("%H:%M:%S.%3f").to_string()
89                }
90            },
91        }
92    }
93
94    pub(crate) fn csv_headers() -> String {
95        format!(
96            "{},{},{},{},{},{}",
97            "ramp_up", "repeat", "min_sec", "max_sec", "median_sec", "std_dev_sec",
98        )
99    }
100
101    pub(crate) fn as_csv(&self) -> String {
102        format!(
103            "{},{},{},{},{},{}",
104            self.ramp_up,
105            self.repeat,
106            self.min_sec,
107            self.max_sec,
108            self.median_sec,
109            self.std_dev_sec.unwrap_or(0.0),
110        )
111    }
112}