hydro_std/bench_client/
rolling_average.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Clone, Debug, Serialize, Deserialize)]
5pub struct RollingAverage {
6 samples: Vec<f64>,
7 sum: f64,
8 sum_squares: f64,
9 count: usize,
10}
11
12impl Default for RollingAverage {
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl RollingAverage {
19 pub fn new() -> Self {
20 Self {
21 samples: Vec::new(),
22 sum: 0.0,
23 sum_squares: 0.0,
24 count: 0,
25 }
26 }
27
28 pub fn add_sample(&mut self, value: f64) {
29 self.samples.push(value);
30 self.sum += value;
31 self.sum_squares += value * value;
32 self.count += 1;
33 }
34
35 pub fn sample_count(&self) -> usize {
36 self.count
37 }
38
39 pub fn sample_mean(&self) -> f64 {
40 if self.count == 0 {
41 0.0
42 } else {
43 self.sum / self.count as f64
44 }
45 }
46
47 pub fn sample_variance(&self) -> f64 {
48 if self.count <= 1 {
49 0.0
50 } else {
51 let mean = self.sample_mean();
52 (self.sum_squares - self.count as f64 * mean * mean) / (self.count - 1) as f64
53 }
54 }
55
56 pub fn sample_std_dev(&self) -> f64 {
57 self.sample_variance().sqrt()
58 }
59
60 pub fn confidence_interval_99(&self) -> Option<(f64, f64)> {
62 if self.count < 2 {
63 return None;
64 }
65
66 let mean = self.sample_mean();
67 let std_dev = self.sample_std_dev();
68 let std_error = std_dev / (self.count as f64).sqrt();
69
70 let t_value = 2.576; let margin = t_value * std_error;
74 Some((mean - margin, mean + margin))
75 }
76
77 pub fn add(&mut self, other: Self) {
79 for sample in other.samples {
80 self.add_sample(sample);
81 }
82 }
83}