github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/qpc/count.go (about) 1 package qpc 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "time" 8 9 "github.com/montanaflynn/stats" 10 ) 11 12 type Count int64 13 14 func Since(start Count) time.Duration { 15 return Now().Sub(start).Duration() 16 } 17 18 type checkpoint struct { 19 name string 20 duration time.Duration 21 } 22 23 type History struct { 24 name string 25 values []time.Duration 26 start Count 27 last time.Duration 28 } 29 30 func NewHistory(name string) *History { return &History{name: name} } 31 32 func (hist *History) Start() { hist.start = Now() } 33 func (hist *History) Stop() { 34 now := Now() 35 hist.last = now.Sub(hist.start).Duration() 36 hist.values = append(hist.values, hist.last) 37 } 38 39 func (hist *History) SampleCount() int { return len(hist.values) } 40 41 func (hist *History) Last() time.Duration { return hist.last } 42 43 func (hist *History) PrintSummary() { 44 nanos := []float64{} 45 for _, duration := range hist.values { 46 nanos = append(nanos, float64(duration)) 47 } 48 49 fmt.Printf("%10s", hist.name) 50 min, _ := stats.Min(nanos) 51 fmt.Printf(" %10s", time.Duration(min)) 52 for _, p := range percentiles { 53 per, _ := stats.Percentile(nanos, p) 54 nano := time.Duration(per) 55 fmt.Printf(" %10s", nano) 56 } 57 max, _ := stats.Max(nanos) 58 fmt.Printf(" %10s", time.Duration(max)) 59 fmt.Println() 60 } 61 62 var percentiles = []float64{10, 25, 50, 75, 90} 63 64 func FprintSummary(out io.Writer, hists ...*History) { 65 fmt.Fprintf(out, "%10s", "") 66 fmt.Fprintf(out, " %10s", "MIN") 67 for _, p := range percentiles { 68 fmt.Fprintf(out, " %9d%%", int(p)) 69 } 70 fmt.Fprintf(out, " %10s", "MAX") 71 fmt.Fprintln(out) 72 73 for _, hist := range hists { 74 nanos := []float64{} 75 for _, duration := range hist.values { 76 nanos = append(nanos, float64(duration)) 77 } 78 79 fmt.Fprintf(out, "%10s", hist.name) 80 min, _ := stats.Min(nanos) 81 fmt.Fprintf(out, " %10s", time.Duration(min)) 82 for _, p := range percentiles { 83 per, _ := stats.Percentile(nanos, p) 84 fmt.Fprintf(out, " %10s", time.Duration(per)) 85 } 86 max, _ := stats.Max(nanos) 87 fmt.Fprintf(out, " %10s", time.Duration(max)) 88 fmt.Fprintln(out) 89 } 90 } 91 92 func PrintSummary(hists ...*History) { 93 FprintSummary(os.Stdout, hists...) 94 }