github.com/minio/madmin-go@v1.7.5/timings.go (about) 1 // 2 // MinIO Object Storage (c) 2022 MinIO, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package madmin 18 19 import ( 20 "math" 21 "sort" 22 "time" 23 ) 24 25 // Timings captures all latency metrics 26 type Timings struct { 27 Avg time.Duration `json:"avg"` // Average duration per sample 28 P50 time.Duration `json:"p50"` // 50th %ile of all the sample durations 29 P75 time.Duration `json:"p75"` // 75th %ile of all the sample durations 30 P95 time.Duration `json:"p95"` // 95th %ile of all the sample durations 31 P99 time.Duration `json:"p99"` // 99th %ile of all the sample durations 32 P999 time.Duration `json:"p999"` // 99.9th %ile of all the sample durations 33 Long5p time.Duration `json:"l5p"` // Average duration of the longest 5% 34 Short5p time.Duration `json:"s5p"` // Average duration of the shortest 5% 35 Max time.Duration `json:"max"` // Max duration 36 Min time.Duration `json:"min"` // Min duration 37 StdDev time.Duration `json:"sdev"` // Standard deviation among all the sample durations 38 Range time.Duration `json:"range"` // Delta between Max and Min 39 } 40 41 // Measure - calculate all the latency measurements 42 func (ts TimeDurations) Measure() Timings { 43 if len(ts) == 0 { 44 return Timings{ 45 Avg: 0, 46 P50: 0, 47 P75: 0, 48 P95: 0, 49 P99: 0, 50 P999: 0, 51 Long5p: 0, 52 Short5p: 0, 53 Min: 0, 54 Max: 0, 55 Range: 0, 56 StdDev: 0, 57 } 58 } 59 sort.Slice(ts, func(i, j int) bool { 60 return int64(ts[i]) < int64(ts[j]) 61 }) 62 return Timings{ 63 Avg: ts.avg(), 64 P50: ts[ts.Len()/2], 65 P75: ts.p(0.75), 66 P95: ts.p(0.95), 67 P99: ts.p(0.99), 68 P999: ts.p(0.999), 69 Long5p: ts.long5p(), 70 Short5p: ts.short5p(), 71 Min: ts.min(), 72 Max: ts.max(), 73 Range: ts.srange(), 74 StdDev: ts.stdDev(), 75 } 76 } 77 78 // TimeDurations is time.Duration segments. 79 type TimeDurations []time.Duration 80 81 func (ts TimeDurations) Len() int { return len(ts) } 82 83 func (ts TimeDurations) avg() time.Duration { 84 var total time.Duration 85 for _, t := range ts { 86 total += t 87 } 88 return time.Duration(int(total) / ts.Len()) 89 } 90 91 func (ts TimeDurations) p(p float64) time.Duration { 92 return ts[int(float64(ts.Len())*p+0.5)-1] 93 } 94 95 func (ts TimeDurations) stdDev() time.Duration { 96 m := ts.avg() 97 s := 0.00 98 99 for _, t := range ts { 100 s += math.Pow(float64(m-t), 2) 101 } 102 103 msq := s / float64(ts.Len()) 104 105 return time.Duration(math.Sqrt(msq)) 106 } 107 108 func (ts TimeDurations) long5p() time.Duration { 109 set := ts[int(float64(ts.Len())*0.95+0.5):] 110 111 if len(set) <= 1 { 112 return ts[ts.Len()-1] 113 } 114 115 var t time.Duration 116 var i int 117 for _, n := range set { 118 t += n 119 i++ 120 } 121 122 return time.Duration(int(t) / i) 123 } 124 125 func (ts TimeDurations) short5p() time.Duration { 126 set := ts[:int(float64(ts.Len())*0.05+0.5)] 127 128 if len(set) <= 1 { 129 return ts[0] 130 } 131 132 var t time.Duration 133 var i int 134 for _, n := range set { 135 t += n 136 i++ 137 } 138 139 return time.Duration(int(t) / i) 140 } 141 142 func (ts TimeDurations) min() time.Duration { 143 return ts[0] 144 } 145 146 func (ts TimeDurations) max() time.Duration { 147 return ts[ts.Len()-1] 148 } 149 150 func (ts TimeDurations) srange() time.Duration { 151 return ts.max() - ts.min() 152 }