ying_profiler/
histogram.rs1use std::fmt;
2
3const BUCKETS_MILLIS: &[u64] = &[1000, 5_000, 10_000, 30_000, 100_000, u64::MAX];
5const NUM_BUCKETS: usize = BUCKETS_MILLIS.len();
6
7#[derive(Copy, Clone, Debug)]
10pub struct MillisHistogram {
11 counts: [u64; NUM_BUCKETS],
12 sum: u64,
13 count: u64, }
15
16impl Default for MillisHistogram {
17 fn default() -> Self {
18 Self::new()
19 }
20}
21
22impl MillisHistogram {
23 pub fn new() -> Self {
24 Self {
25 counts: [0; NUM_BUCKETS],
26 sum: 0,
27 count: 0,
28 }
29 }
30
31 pub(crate) fn add_sample(&mut self, millis: u64) {
32 self.count += 1;
33 self.sum += millis;
34 match BUCKETS_MILLIS.binary_search(&millis) {
35 Ok(index) if index < NUM_BUCKETS => self.counts[index] += 1,
36 Err(index) if index < NUM_BUCKETS => self.counts[index] += 1,
37 _ => {}
38 }
39 }
40
41 pub fn average_millis(&self) -> f64 {
42 self.sum as f64 / self.count as f64
43 }
44
45 pub fn counts(&self) -> [u64; NUM_BUCKETS] {
46 self.counts
47 }
48
49 }
51
52impl fmt::Display for MillisHistogram {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 write!(
55 f,
56 "Histogram avg: {:.2}secs {{",
57 self.average_millis() / 1000.0
58 )?;
59 for (bucket, count) in BUCKETS_MILLIS.iter().zip(self.counts) {
60 write!(f, "{:.2}s: {}, ", *bucket as f64 / 1000.0, count)?;
61 }
62 write!(f, "}}")?;
63 Ok(())
64 }
65}