github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/utilities/metrics/sample_test.go (about) 1 package metrics 2 3 import ( 4 "math/rand" 5 "runtime" 6 "testing" 7 "time" 8 ) 9 10 func BenchmarkCompute1000(b *testing.B) { 11 s := make([]int64, 1000) 12 for i := 0; i < len(s); i++ { 13 s[i] = int64(i) 14 } 15 b.ResetTimer() 16 for i := 0; i < b.N; i++ { 17 SampleVariance(s) 18 } 19 } 20 func BenchmarkCompute1000000(b *testing.B) { 21 s := make([]int64, 1000000) 22 for i := 0; i < len(s); i++ { 23 s[i] = int64(i) 24 } 25 b.ResetTimer() 26 for i := 0; i < b.N; i++ { 27 SampleVariance(s) 28 } 29 } 30 func BenchmarkCopy1000(b *testing.B) { 31 s := make([]int64, 1000) 32 for i := 0; i < len(s); i++ { 33 s[i] = int64(i) 34 } 35 b.ResetTimer() 36 for i := 0; i < b.N; i++ { 37 sCopy := make([]int64, len(s)) 38 copy(sCopy, s) 39 } 40 } 41 func BenchmarkCopy1000000(b *testing.B) { 42 s := make([]int64, 1000000) 43 for i := 0; i < len(s); i++ { 44 s[i] = int64(i) 45 } 46 b.ResetTimer() 47 for i := 0; i < b.N; i++ { 48 sCopy := make([]int64, len(s)) 49 copy(sCopy, s) 50 } 51 } 52 53 func BenchmarkExpDecaySample257(b *testing.B) { 54 benchmarkSample(b, NewExpDecaySample(257, 0.015)) 55 } 56 57 func BenchmarkExpDecaySample514(b *testing.B) { 58 benchmarkSample(b, NewExpDecaySample(514, 0.015)) 59 } 60 61 func BenchmarkExpDecaySample1028(b *testing.B) { 62 benchmarkSample(b, NewExpDecaySample(1028, 0.015)) 63 } 64 65 func BenchmarkUniformSample257(b *testing.B) { 66 benchmarkSample(b, NewUniformSample(257)) 67 } 68 69 func BenchmarkUniformSample514(b *testing.B) { 70 benchmarkSample(b, NewUniformSample(514)) 71 } 72 73 func BenchmarkUniformSample1028(b *testing.B) { 74 benchmarkSample(b, NewUniformSample(1028)) 75 } 76 77 func TestExpDecaySample10(t *testing.T) { 78 rand.Seed(1) 79 s := NewExpDecaySample(100, 0.99) 80 for i := 0; i < 10; i++ { 81 s.Update(int64(i)) 82 } 83 if size := s.Count(); 10 != size { 84 t.Errorf("s.Count(): 10 != %v\n", size) 85 } 86 if size := s.Size(); 10 != size { 87 t.Errorf("s.Size(): 10 != %v\n", size) 88 } 89 if l := len(s.Values()); 10 != l { 90 t.Errorf("len(s.Values()): 10 != %v\n", l) 91 } 92 for _, v := range s.Values() { 93 if v > 10 || v < 0 { 94 t.Errorf("out of range [0, 10): %v\n", v) 95 } 96 } 97 } 98 99 func TestExpDecaySample100(t *testing.T) { 100 rand.Seed(1) 101 s := NewExpDecaySample(1000, 0.01) 102 for i := 0; i < 100; i++ { 103 s.Update(int64(i)) 104 } 105 if size := s.Count(); 100 != size { 106 t.Errorf("s.Count(): 100 != %v\n", size) 107 } 108 if size := s.Size(); 100 != size { 109 t.Errorf("s.Size(): 100 != %v\n", size) 110 } 111 if l := len(s.Values()); 100 != l { 112 t.Errorf("len(s.Values()): 100 != %v\n", l) 113 } 114 for _, v := range s.Values() { 115 if v > 100 || v < 0 { 116 t.Errorf("out of range [0, 100): %v\n", v) 117 } 118 } 119 } 120 121 func TestExpDecaySample1000(t *testing.T) { 122 rand.Seed(1) 123 s := NewExpDecaySample(100, 0.99) 124 for i := 0; i < 1000; i++ { 125 s.Update(int64(i)) 126 } 127 if size := s.Count(); 1000 != size { 128 t.Errorf("s.Count(): 1000 != %v\n", size) 129 } 130 if size := s.Size(); 100 != size { 131 t.Errorf("s.Size(): 100 != %v\n", size) 132 } 133 if l := len(s.Values()); 100 != l { 134 t.Errorf("len(s.Values()): 100 != %v\n", l) 135 } 136 for _, v := range s.Values() { 137 if v > 1000 || v < 0 { 138 t.Errorf("out of range [0, 1000): %v\n", v) 139 } 140 } 141 } 142 143 func TestExpDecaySampleNanosecondRegression(t *testing.T) { 144 rand.Seed(1) 145 s := NewExpDecaySample(100, 0.99) 146 for i := 0; i < 100; i++ { 147 s.Update(10) 148 } 149 time.Sleep(1 * time.Millisecond) 150 for i := 0; i < 100; i++ { 151 s.Update(20) 152 } 153 v := s.Values() 154 avg := float64(0) 155 for i := 0; i < len(v); i++ { 156 avg += float64(v[i]) 157 } 158 avg /= float64(len(v)) 159 if avg > 16 || avg < 14 { 160 t.Errorf("out of range [14, 16]: %v\n", avg) 161 } 162 } 163 164 func TestExpDecaySampleRescale(t *testing.T) { 165 s := NewExpDecaySample(2, 0.001).(*ExpDecaySample) 166 s.update(time.Now(), 1) 167 s.update(time.Now().Add(time.Hour+time.Microsecond), 1) 168 for _, v := range s.values.Values() { 169 if v.k == 0.0 { 170 t.Fatal("v.k == 0.0") 171 } 172 } 173 } 174 175 func TestExpDecaySampleSnapshot(t *testing.T) { 176 now := time.Now() 177 rand.Seed(1) 178 s := NewExpDecaySample(100, 0.99) 179 for i := 1; i <= 10000; i++ { 180 s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i)) 181 } 182 snapshot := s.Snapshot() 183 s.Update(1) 184 testExpDecaySampleStatistics(t, snapshot) 185 } 186 187 func TestExpDecaySampleStatistics(t *testing.T) { 188 now := time.Now() 189 rand.Seed(1) 190 s := NewExpDecaySample(100, 0.99) 191 for i := 1; i <= 10000; i++ { 192 s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i)) 193 } 194 testExpDecaySampleStatistics(t, s) 195 } 196 197 func TestUniformSample(t *testing.T) { 198 rand.Seed(1) 199 s := NewUniformSample(100) 200 for i := 0; i < 1000; i++ { 201 s.Update(int64(i)) 202 } 203 if size := s.Count(); 1000 != size { 204 t.Errorf("s.Count(): 1000 != %v\n", size) 205 } 206 if size := s.Size(); 100 != size { 207 t.Errorf("s.Size(): 100 != %v\n", size) 208 } 209 if l := len(s.Values()); 100 != l { 210 t.Errorf("len(s.Values()): 100 != %v\n", l) 211 } 212 for _, v := range s.Values() { 213 if v > 1000 || v < 0 { 214 t.Errorf("out of range [0, 100): %v\n", v) 215 } 216 } 217 } 218 219 func TestUniformSampleIncludesTail(t *testing.T) { 220 rand.Seed(1) 221 s := NewUniformSample(100) 222 max := 100 223 for i := 0; i < max; i++ { 224 s.Update(int64(i)) 225 } 226 v := s.Values() 227 sum := 0 228 exp := (max - 1) * max / 2 229 for i := 0; i < len(v); i++ { 230 sum += int(v[i]) 231 } 232 if exp != sum { 233 t.Errorf("sum: %v != %v\n", exp, sum) 234 } 235 } 236 237 func TestUniformSampleSnapshot(t *testing.T) { 238 s := NewUniformSample(100) 239 for i := 1; i <= 10000; i++ { 240 s.Update(int64(i)) 241 } 242 snapshot := s.Snapshot() 243 s.Update(1) 244 testUniformSampleStatistics(t, snapshot) 245 } 246 247 func TestUniformSampleStatistics(t *testing.T) { 248 rand.Seed(1) 249 s := NewUniformSample(100) 250 for i := 1; i <= 10000; i++ { 251 s.Update(int64(i)) 252 } 253 testUniformSampleStatistics(t, s) 254 } 255 256 func benchmarkSample(b *testing.B, s Sample) { 257 var memStats runtime.MemStats 258 runtime.ReadMemStats(&memStats) 259 pauseTotalNs := memStats.PauseTotalNs 260 b.ResetTimer() 261 for i := 0; i < b.N; i++ { 262 s.Update(1) 263 } 264 b.StopTimer() 265 runtime.GC() 266 runtime.ReadMemStats(&memStats) 267 b.Logf("GC cost: %d ns/op", int(memStats.PauseTotalNs-pauseTotalNs)/b.N) 268 } 269 270 func testExpDecaySampleStatistics(t *testing.T, s Sample) { 271 if count := s.Count(); 10000 != count { 272 t.Errorf("s.Count(): 10000 != %v\n", count) 273 } 274 if min := s.Min(); 107 != min { 275 t.Errorf("s.Min(): 107 != %v\n", min) 276 } 277 if max := s.Max(); 10000 != max { 278 t.Errorf("s.Max(): 10000 != %v\n", max) 279 } 280 if mean := s.Mean(); 4965.98 != mean { 281 t.Errorf("s.Mean(): 4965.98 != %v\n", mean) 282 } 283 if stdDev := s.StdDev(); 2959.825156930727 != stdDev { 284 t.Errorf("s.StdDev(): 2959.825156930727 != %v\n", stdDev) 285 } 286 ps := s.Percentiles([]float64{0.5, 0.75, 0.99}) 287 if 4615 != ps[0] { 288 t.Errorf("median: 4615 != %v\n", ps[0]) 289 } 290 if 7672 != ps[1] { 291 t.Errorf("75th percentile: 7672 != %v\n", ps[1]) 292 } 293 if 9998.99 != ps[2] { 294 t.Errorf("99th percentile: 9998.99 != %v\n", ps[2]) 295 } 296 } 297 298 func testUniformSampleStatistics(t *testing.T, s Sample) { 299 if count := s.Count(); 10000 != count { 300 t.Errorf("s.Count(): 10000 != %v\n", count) 301 } 302 if min := s.Min(); 37 != min { 303 t.Errorf("s.Min(): 37 != %v\n", min) 304 } 305 if max := s.Max(); 9989 != max { 306 t.Errorf("s.Max(): 9989 != %v\n", max) 307 } 308 if mean := s.Mean(); 4748.14 != mean { 309 t.Errorf("s.Mean(): 4748.14 != %v\n", mean) 310 } 311 if stdDev := s.StdDev(); 2826.684117548333 != stdDev { 312 t.Errorf("s.StdDev(): 2826.684117548333 != %v\n", stdDev) 313 } 314 ps := s.Percentiles([]float64{0.5, 0.75, 0.99}) 315 if 4599 != ps[0] { 316 t.Errorf("median: 4599 != %v\n", ps[0]) 317 } 318 if 7380.5 != ps[1] { 319 t.Errorf("75th percentile: 7380.5 != %v\n", ps[1]) 320 } 321 if 9986.429999999998 != ps[2] { 322 t.Errorf("99th percentile: 9986.429999999998 != %v\n", ps[2]) 323 } 324 } 325 326 func TestUniformSampleConcurrentUpdateCount(t *testing.T) { 327 if testing.Short() { 328 t.Skip("skipping in short mode") 329 } 330 s := NewUniformSample(100) 331 for i := 0; i < 100; i++ { 332 s.Update(int64(i)) 333 } 334 quit := make(chan struct{}) 335 go func() { 336 t := time.NewTicker(10 * time.Millisecond) 337 for { 338 select { 339 case <-t.C: 340 s.Update(rand.Int63()) 341 case <-quit: 342 t.Stop() 343 return 344 } 345 } 346 }() 347 for i := 0; i < 1000; i++ { 348 s.Count() 349 time.Sleep(5 * time.Millisecond) 350 } 351 quit <- struct{}{} 352 }