1use core::cell::RefCell;
3use minstant::Instant;
4use sketches_ddsketch::{Config, DDSketch};
5use std::rc::Rc;
6
7pub fn sketch_percentiles(sketch: &DDSketch) -> Percentiles {
8 Percentiles {
9 count: sketch.count(),
10 min: sketch.min().unwrap_or(0.0),
11 p25: sketch.quantile(0.25).unwrap().unwrap_or(0.0),
12 p50: sketch.quantile(0.5).unwrap().unwrap_or(0.0),
13 p75: sketch.quantile(0.75).unwrap().unwrap_or(0.0),
14 p95: sketch.quantile(0.95).unwrap().unwrap_or(0.0),
15 p99: sketch.quantile(0.99).unwrap().unwrap_or(0.0),
16 p99_9: sketch.quantile(0.999).unwrap().unwrap_or(0.0),
17 p99_99: sketch.quantile(0.9999).unwrap().unwrap_or(0.0),
18 p99_999: sketch.quantile(0.99999).unwrap().unwrap_or(0.0),
19 max: sketch.max().unwrap_or(0.0),
20 sum: sketch.sum().unwrap_or(0.0),
21 }
22}
23
24#[derive(Default, Clone, Copy)]
25pub struct Percentiles {
26 pub count: usize,
27 pub min: f64,
28 pub p25: f64,
29 pub p50: f64,
30 pub p75: f64,
31 pub p95: f64,
32 pub p99: f64,
33 pub p99_9: f64,
34 pub p99_99: f64,
35 pub p99_999: f64,
36 pub max: f64,
37 pub sum: f64,
38}
39
40impl std::fmt::Debug for Percentiles {
41 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42 f.debug_struct("Percentiles")
43 .field("count", &self.count)
44 .field("min", &format_args!("{:.2}ns", self.min))
45 .field("p25", &format_args!("{:.2}ns", self.p25))
46 .field("p50", &format_args!("{:.2}ns", self.p50))
47 .field("p75", &format_args!("{:.2}ns", self.p75))
48 .field("p95", &format_args!("{:.2}ns", self.p95))
49 .field("p99", &format_args!("{:.2}ns", self.p99))
50 .field("p99.9", &format_args!("{:.2}ns", self.p99_9))
51 .field("p99.99", &format_args!("{:.2}ns", self.p99_99))
52 .field("p99.999", &format_args!("{:.2}ns", self.p99_999))
53 .field("max", &format_args!("{:.2}ns", self.max))
54 .field("sum", &self.sum)
55 .finish()
56 }
57}
58
59#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
60#[derive(Clone)]
61pub struct Sketch {
62 inner: Rc<RefCell<DDSketch>>,
63}
64impl Default for Sketch {
65 fn default() -> Self {
66 Self {
67 inner: Rc::new(RefCell::new(DDSketch::new(Config::new(0.01, 2048, 1.0e-9)))),
68 }
69 }
70}
71impl Sketch {
72 #[inline]
73 pub fn add(&self, data: f64) {
74 self.inner.borrow_mut().add(data)
75 }
76 pub fn merge(&self, other: Self) {
77 self.inner
78 .borrow_mut()
79 .merge(&other.inner.borrow())
80 .unwrap()
81 }
82 pub fn percentiles(&self) -> Percentiles {
83 sketch_percentiles(&self.inner.borrow())
84 }
85 pub fn count(&self) -> usize {
86 self.inner.borrow().count()
87 }
88}
89
90pub struct Measure {
92 start: Instant,
93 sketch: Sketch,
94}
95
96impl Measure {
97 #[inline]
98 #[allow(unused_variables)]
99 pub fn new(sketch: &Sketch) -> Measure {
100 Measure {
101 sketch: sketch.clone(), start: Instant::now(),
103 }
104 }
105}
106
107impl Drop for Measure {
108 #[inline]
109 fn drop(&mut self) {
110 self.sketch.add(self.start.elapsed().as_nanos() as f64);
111 }
112}
113
114#[macro_export]
128macro_rules! profile_scope {
129 ($id:expr) => {
130 let _measure_scope = $crate::Measure::new($id);
131 };
132}