internal/histogram.go (38 lines of code) (raw):

package internal import ( "fmt" "math" "go.uber.org/atomic" ) type TimeHistogram struct { Count atomic.Int64 Sum atomic.Float64 SumSquare atomic.Float64 } func (h *TimeHistogram) AddSample(us float64) { h.Count.Inc() h.Sum.Add(us) h.SumSquare.Add(us * us) } func (h *TimeHistogram) String() string { avg := h.Avg() stdDev := h.StdDev() count := h.Count.Load() return fmt.Sprintf("{avg: %.1fus, stdDev: %.1fus, count: %d}", avg, stdDev, count) } func (h *TimeHistogram) Avg() float64 { count := h.Count.Load() if count == 0 { return 0 } return h.Sum.Load() / float64(count) } func (h *TimeHistogram) StdDev() float64 { count := h.Count.Load() if count < 2 { return 0 } div := float64(count * (count - 1)) num := (float64(count) * h.SumSquare.Load()) - math.Pow(h.Sum.Load(), 2) return math.Sqrt(num / div) }