Coverage Report

Created: 2023-02-22 06:51

/src/hermes/include/hermes/Support/StatsAccumulator.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) Meta Platforms, Inc. and affiliates.
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
8
#ifndef HERMES_SUPPORT_STATSACCUMULATOR_H
9
#define HERMES_SUPPORT_STATSACCUMULATOR_H
10
11
#include <algorithm>
12
#include <cmath>
13
14
namespace hermes {
15
16
/// Gathers summary statistics for a sequence of samples for a
17
/// statistic of type T.  The statistic type T must be convertible to
18
/// double.  SumT is provided for cases where the sum of the samples
19
/// might overflow the type T.  T must be convertible to SumT, and
20
/// SumT must be convertible to double.
21
template <typename T, typename SumT = T>
22
class StatsAccumulator {
23
 public:
24
1.18k
  StatsAccumulator() = default;
hermes::StatsAccumulator<double, double>::StatsAccumulator()
Line
Count
Source
24
594
  StatsAccumulator() = default;
hermes::StatsAccumulator<unsigned int, unsigned long>::StatsAccumulator()
Line
Count
Source
24
594
  StatsAccumulator() = default;
25
26
  /// Update the summary stats with the addition of a new \p value.
27
3.76k
  inline void record(T value) {
28
3.76k
    if (n_ == 0) {
29
87
      min_ = value;
30
87
      max_ = value;
31
3.67k
    } else {
32
3.67k
      min_ = std::min(min_, value);
33
3.67k
      max_ = std::max(max_, value);
34
3.67k
    }
35
3.76k
    n_++;
36
3.76k
    sum_ += value;
37
3.76k
    double valD = static_cast<double>(value);
38
3.76k
    sumOfSquares_ += valD * valD;
39
3.76k
  }
hermes::StatsAccumulator<double, double>::record(double)
Line
Count
Source
27
1.74k
  inline void record(T value) {
28
1.74k
    if (n_ == 0) {
29
41
      min_ = value;
30
41
      max_ = value;
31
1.70k
    } else {
32
1.70k
      min_ = std::min(min_, value);
33
1.70k
      max_ = std::max(max_, value);
34
1.70k
    }
35
1.74k
    n_++;
36
1.74k
    sum_ += value;
37
1.74k
    double valD = static_cast<double>(value);
38
1.74k
    sumOfSquares_ += valD * valD;
39
1.74k
  }
hermes::StatsAccumulator<unsigned int, unsigned long>::record(unsigned int)
Line
Count
Source
27
2.01k
  inline void record(T value) {
28
2.01k
    if (n_ == 0) {
29
46
      min_ = value;
30
46
      max_ = value;
31
1.97k
    } else {
32
1.97k
      min_ = std::min(min_, value);
33
1.97k
      max_ = std::max(max_, value);
34
1.97k
    }
35
2.01k
    n_++;
36
2.01k
    sum_ += value;
37
2.01k
    double valD = static_cast<double>(value);
38
2.01k
    sumOfSquares_ += valD * valD;
39
2.01k
  }
40
41
  /// Accessors
42
43
  /// \return the number of samples recorded.
44
  inline unsigned count() const {
45
    return n_;
46
  }
47
48
  /// \return the minimum of the samples recorded.
49
  inline T min() const {
50
    return min_;
51
  }
52
53
  /// \return the maximum of the samples recorded.
54
0
  inline T max() const {
55
0
    return max_;
56
0
  }
Unexecuted instantiation: hermes::StatsAccumulator<unsigned int, unsigned long>::max() const
Unexecuted instantiation: hermes::StatsAccumulator<double, double>::max() const
57
58
  /// \return the sum of the samples recorded.
59
0
  inline SumT sum() const {
60
0
    return sum_;
61
0
  }
62
63
  /// Returns the average of the recorded samples.
64
0
  inline double average() const {
65
0
    return n_ == 0 ? 0.0 : static_cast<double>(sum_) / n_;
66
0
  }
67
68
  /// \return the sum of the squares of the samples recorded.
69
0
  inline double sumOfSquares() const {
70
0
    return sumOfSquares_;
71
0
  }
72
73
  /// Returns the standard deviation of the recorded samples.
74
  inline double stddev() const;
75
76
 private:
77
  /// Number of samples recorded.
78
  unsigned n_{0};
79
  /// Sum of the samples.
80
  SumT sum_{0};
81
  /// Minimum sample.
82
  T min_{0};
83
  /// Maximum sample.
84
  T max_{0};
85
  /// Sum of the squares of the durations (necessary for standard
86
  /// devation).  We assume that because of the squaring, it may grow
87
  /// large, so always use double for this value.
88
  double sumOfSquares_{0.0};
89
};
90
91
template <typename T, typename SumT>
92
inline double StatsAccumulator<T, SumT>::stddev() const {
93
  if (n_ == 0) {
94
    return 0.0;
95
  }
96
  double avg = average();
97
  // See, e.g.,
98
  // https://math.stackexchange.com/questions/198336/how-to-calculate-standard-deviation-with-streaming-inputs
99
  // for an explanation.
100
  double variance = (sumOfSquares_ / n_) - (avg * avg);
101
  return std::sqrt(variance);
102
}
103
104
} // namespace hermes
105
106
#endif // HERMES_SUPPORT_STATSACCUMULATOR_H