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  }