github.com/xgzlucario/GigaCache@v0.0.0-20240508025442-54204e9c8a6b/example/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "runtime" 6 "slices" 7 "strconv" 8 "time" 9 10 "net/http" 11 _ "net/http/pprof" 12 13 cache "github.com/xgzlucario/GigaCache" 14 ) 15 16 type Quantile struct { 17 f []float64 18 } 19 20 func NewQuantile(size int) *Quantile { 21 return &Quantile{f: make([]float64, 0, size)} 22 } 23 24 func (q *Quantile) Add(v float64) { 25 q.f = append(q.f, v) 26 } 27 28 func (q *Quantile) quantile(p float64) float64 { 29 r := q.f[int(float64(len(q.f))*p)] 30 return r 31 } 32 33 func (q *Quantile) Print() { 34 slices.Sort(q.f) 35 fmt.Printf("90th: %.0f ns\n", q.quantile(0.9)) 36 fmt.Printf("99th: %.0f ns\n", q.quantile(0.99)) 37 fmt.Printf("999th: %.0f ns\n", q.quantile(0.999)) 38 } 39 40 const N = 100 * 10000 41 42 func main() { 43 go func() { 44 _ = http.ListenAndServe("localhost:6060", nil) 45 }() 46 47 options := cache.DefaultOptions 48 49 for _, arg := range []int{3} { 50 options.EvictInterval = arg 51 fmt.Println("=====Options=====") 52 fmt.Printf("%+v\n", options) 53 benchmark(options) 54 runtime.GC() 55 } 56 } 57 58 func benchmark(options cache.Options) { 59 quant := NewQuantile(N) 60 61 var count int64 62 var memStats runtime.MemStats 63 64 bc := cache.New(options) 65 66 // Set test 67 start := time.Now() 68 var now time.Time 69 for j := 0; ; j++ { 70 k := strconv.FormatUint(cache.FastRand64(), 36) 71 72 if j%10 == 0 { 73 now = time.Now() 74 if now.Sub(start) > time.Minute { 75 break 76 } 77 } 78 79 bc.SetEx(k, []byte(k), time.Second) 80 count++ 81 82 if j%10 == 0 { 83 cost := float64(time.Since(now)) / float64(time.Nanosecond) 84 quant.Add(cost) 85 } 86 } 87 88 // Stat 89 stat := bc.Stat() 90 91 fmt.Printf("[Cache] %.0fs | %dw | len: %dw | alloc: %v (unused: %.1f%%)\n", 92 time.Since(start).Seconds(), 93 count/1e4, 94 stat.Len/1e4, 95 formatSize(stat.Alloc), 96 stat.UnusedRate(), 97 ) 98 fmt.Printf("[Evict] probe: %vw / %vw (%.1f%%) | mgr: %d\n", 99 stat.Evict/1e5, stat.Probe/1e5, stat.EvictRate(), 100 stat.Migrates) 101 102 // mem stats 103 runtime.ReadMemStats(&memStats) 104 fmt.Printf("[Mem] mem: %.0fMB | sys: %.0fMB | gc: %d | gcpause: %.0f us\n", 105 float64(memStats.Alloc)/1024/1024, 106 float64(memStats.Sys)/1024/1024, 107 memStats.NumGC, 108 float64(memStats.PauseTotalNs)/float64(memStats.NumGC)/1000) 109 110 // quant print 111 quant.Print() 112 113 fmt.Println("-----------------------------------------------------") 114 } 115 116 const ( 117 KB = 1024 118 MB = 1024 * KB 119 ) 120 121 // formatSize 122 func formatSize[T float64 | uint64](size T) string { 123 switch { 124 case size < KB: 125 return fmt.Sprintf("%.0fB", float64(size)) 126 case size < MB: 127 return fmt.Sprintf("%.1fKB", float64(size)/KB) 128 default: 129 return fmt.Sprintf("%.1fMB", float64(size)/MB) 130 } 131 }