github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/metrics/sample_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:40</date> 10 //</624450100113969152> 11 12 package metrics 13 14 import ( 15 "math/rand" 16 "runtime" 17 "testing" 18 "time" 19 ) 20 21 //基准计算,复制1000000证明,即使相对而言 22 //昂贵的计算,如方差,复制样本的成本,如 23 //近似于一份复制品,比 24 //对小样本的计算,而对大样本的计算则稍微少一些。 25 func BenchmarkCompute1000(b *testing.B) { 26 s := make([]int64, 1000) 27 for i := 0; i < len(s); i++ { 28 s[i] = int64(i) 29 } 30 b.ResetTimer() 31 for i := 0; i < b.N; i++ { 32 SampleVariance(s) 33 } 34 } 35 func BenchmarkCompute1000000(b *testing.B) { 36 s := make([]int64, 1000000) 37 for i := 0; i < len(s); i++ { 38 s[i] = int64(i) 39 } 40 b.ResetTimer() 41 for i := 0; i < b.N; i++ { 42 SampleVariance(s) 43 } 44 } 45 func BenchmarkCopy1000(b *testing.B) { 46 s := make([]int64, 1000) 47 for i := 0; i < len(s); i++ { 48 s[i] = int64(i) 49 } 50 b.ResetTimer() 51 for i := 0; i < b.N; i++ { 52 sCopy := make([]int64, len(s)) 53 copy(sCopy, s) 54 } 55 } 56 func BenchmarkCopy1000000(b *testing.B) { 57 s := make([]int64, 1000000) 58 for i := 0; i < len(s); i++ { 59 s[i] = int64(i) 60 } 61 b.ResetTimer() 62 for i := 0; i < b.N; i++ { 63 sCopy := make([]int64, len(s)) 64 copy(sCopy, s) 65 } 66 } 67 68 func BenchmarkExpDecaySample257(b *testing.B) { 69 benchmarkSample(b, NewExpDecaySample(257, 0.015)) 70 } 71 72 func BenchmarkExpDecaySample514(b *testing.B) { 73 benchmarkSample(b, NewExpDecaySample(514, 0.015)) 74 } 75 76 func BenchmarkExpDecaySample1028(b *testing.B) { 77 benchmarkSample(b, NewExpDecaySample(1028, 0.015)) 78 } 79 80 func BenchmarkUniformSample257(b *testing.B) { 81 benchmarkSample(b, NewUniformSample(257)) 82 } 83 84 func BenchmarkUniformSample514(b *testing.B) { 85 benchmarkSample(b, NewUniformSample(514)) 86 } 87 88 func BenchmarkUniformSample1028(b *testing.B) { 89 benchmarkSample(b, NewUniformSample(1028)) 90 } 91 92 func TestExpDecaySample10(t *testing.T) { 93 rand.Seed(1) 94 s := NewExpDecaySample(100, 0.99) 95 for i := 0; i < 10; i++ { 96 s.Update(int64(i)) 97 } 98 if size := s.Count(); 10 != size { 99 t.Errorf("s.Count(): 10 != %v\n", size) 100 } 101 if size := s.Size(); 10 != size { 102 t.Errorf("s.Size(): 10 != %v\n", size) 103 } 104 if l := len(s.Values()); 10 != l { 105 t.Errorf("len(s.Values()): 10 != %v\n", l) 106 } 107 for _, v := range s.Values() { 108 if v > 10 || v < 0 { 109 t.Errorf("out of range [0, 10): %v\n", v) 110 } 111 } 112 } 113 114 func TestExpDecaySample100(t *testing.T) { 115 rand.Seed(1) 116 s := NewExpDecaySample(1000, 0.01) 117 for i := 0; i < 100; i++ { 118 s.Update(int64(i)) 119 } 120 if size := s.Count(); 100 != size { 121 t.Errorf("s.Count(): 100 != %v\n", size) 122 } 123 if size := s.Size(); 100 != size { 124 t.Errorf("s.Size(): 100 != %v\n", size) 125 } 126 if l := len(s.Values()); 100 != l { 127 t.Errorf("len(s.Values()): 100 != %v\n", l) 128 } 129 for _, v := range s.Values() { 130 if v > 100 || v < 0 { 131 t.Errorf("out of range [0, 100): %v\n", v) 132 } 133 } 134 } 135 136 func TestExpDecaySample1000(t *testing.T) { 137 rand.Seed(1) 138 s := NewExpDecaySample(100, 0.99) 139 for i := 0; i < 1000; i++ { 140 s.Update(int64(i)) 141 } 142 if size := s.Count(); 1000 != size { 143 t.Errorf("s.Count(): 1000 != %v\n", size) 144 } 145 if size := s.Size(); 100 != size { 146 t.Errorf("s.Size(): 100 != %v\n", size) 147 } 148 if l := len(s.Values()); 100 != l { 149 t.Errorf("len(s.Values()): 100 != %v\n", l) 150 } 151 for _, v := range s.Values() { 152 if v > 1000 || v < 0 { 153 t.Errorf("out of range [0, 1000): %v\n", v) 154 } 155 } 156 } 157 158 //该测试确保样品的优先级不会因使用 159 //启动后的纳秒持续时间,而不是启动后的第二个持续时间。 160 //启动后,优先级迅速变为+inf,如果这样做, 161 //有效地冻结样本集,直到发生重新缩放步骤。 162 func TestExpDecaySampleNanosecondRegression(t *testing.T) { 163 rand.Seed(1) 164 s := NewExpDecaySample(100, 0.99) 165 for i := 0; i < 100; i++ { 166 s.Update(10) 167 } 168 time.Sleep(1 * time.Millisecond) 169 for i := 0; i < 100; i++ { 170 s.Update(20) 171 } 172 v := s.Values() 173 avg := float64(0) 174 for i := 0; i < len(v); i++ { 175 avg += float64(v[i]) 176 } 177 avg /= float64(len(v)) 178 if avg > 16 || avg < 14 { 179 t.Errorf("out of range [14, 16]: %v\n", avg) 180 } 181 } 182 183 func TestExpDecaySampleRescale(t *testing.T) { 184 s := NewExpDecaySample(2, 0.001).(*ExpDecaySample) 185 s.update(time.Now(), 1) 186 s.update(time.Now().Add(time.Hour+time.Microsecond), 1) 187 for _, v := range s.values.Values() { 188 if v.k == 0.0 { 189 t.Fatal("v.k == 0.0") 190 } 191 } 192 } 193 194 func TestExpDecaySampleSnapshot(t *testing.T) { 195 now := time.Now() 196 rand.Seed(1) 197 s := NewExpDecaySample(100, 0.99) 198 for i := 1; i <= 10000; i++ { 199 s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i)) 200 } 201 snapshot := s.Snapshot() 202 s.Update(1) 203 testExpDecaySampleStatistics(t, snapshot) 204 } 205 206 func TestExpDecaySampleStatistics(t *testing.T) { 207 now := time.Now() 208 rand.Seed(1) 209 s := NewExpDecaySample(100, 0.99) 210 for i := 1; i <= 10000; i++ { 211 s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i)) 212 } 213 testExpDecaySampleStatistics(t, s) 214 } 215 216 func TestUniformSample(t *testing.T) { 217 rand.Seed(1) 218 s := NewUniformSample(100) 219 for i := 0; i < 1000; i++ { 220 s.Update(int64(i)) 221 } 222 if size := s.Count(); 1000 != size { 223 t.Errorf("s.Count(): 1000 != %v\n", size) 224 } 225 if size := s.Size(); 100 != size { 226 t.Errorf("s.Size(): 100 != %v\n", size) 227 } 228 if l := len(s.Values()); 100 != l { 229 t.Errorf("len(s.Values()): 100 != %v\n", l) 230 } 231 for _, v := range s.Values() { 232 if v > 1000 || v < 0 { 233 t.Errorf("out of range [0, 100): %v\n", v) 234 } 235 } 236 } 237 238 func TestUniformSampleIncludesTail(t *testing.T) { 239 rand.Seed(1) 240 s := NewUniformSample(100) 241 max := 100 242 for i := 0; i < max; i++ { 243 s.Update(int64(i)) 244 } 245 v := s.Values() 246 sum := 0 247 exp := (max - 1) * max / 2 248 for i := 0; i < len(v); i++ { 249 sum += int(v[i]) 250 } 251 if exp != sum { 252 t.Errorf("sum: %v != %v\n", exp, sum) 253 } 254 } 255 256 func TestUniformSampleSnapshot(t *testing.T) { 257 s := NewUniformSample(100) 258 for i := 1; i <= 10000; i++ { 259 s.Update(int64(i)) 260 } 261 snapshot := s.Snapshot() 262 s.Update(1) 263 testUniformSampleStatistics(t, snapshot) 264 } 265 266 func TestUniformSampleStatistics(t *testing.T) { 267 rand.Seed(1) 268 s := NewUniformSample(100) 269 for i := 1; i <= 10000; i++ { 270 s.Update(int64(i)) 271 } 272 testUniformSampleStatistics(t, s) 273 } 274 275 func benchmarkSample(b *testing.B, s Sample) { 276 var memStats runtime.MemStats 277 runtime.ReadMemStats(&memStats) 278 pauseTotalNs := memStats.PauseTotalNs 279 b.ResetTimer() 280 for i := 0; i < b.N; i++ { 281 s.Update(1) 282 } 283 b.StopTimer() 284 runtime.GC() 285 runtime.ReadMemStats(&memStats) 286 b.Logf("GC cost: %d ns/op", int(memStats.PauseTotalNs-pauseTotalNs)/b.N) 287 } 288 289 func testExpDecaySampleStatistics(t *testing.T, s Sample) { 290 if count := s.Count(); 10000 != count { 291 t.Errorf("s.Count(): 10000 != %v\n", count) 292 } 293 if min := s.Min(); 107 != min { 294 t.Errorf("s.Min(): 107 != %v\n", min) 295 } 296 if max := s.Max(); 10000 != max { 297 t.Errorf("s.Max(): 10000 != %v\n", max) 298 } 299 if mean := s.Mean(); 4965.98 != mean { 300 t.Errorf("s.Mean(): 4965.98 != %v\n", mean) 301 } 302 if stdDev := s.StdDev(); 2959.825156930727 != stdDev { 303 t.Errorf("s.StdDev(): 2959.825156930727 != %v\n", stdDev) 304 } 305 ps := s.Percentiles([]float64{0.5, 0.75, 0.99}) 306 if 4615 != ps[0] { 307 t.Errorf("median: 4615 != %v\n", ps[0]) 308 } 309 if 7672 != ps[1] { 310 t.Errorf("75th percentile: 7672 != %v\n", ps[1]) 311 } 312 if 9998.99 != ps[2] { 313 t.Errorf("99th percentile: 9998.99 != %v\n", ps[2]) 314 } 315 } 316 317 func testUniformSampleStatistics(t *testing.T, s Sample) { 318 if count := s.Count(); 10000 != count { 319 t.Errorf("s.Count(): 10000 != %v\n", count) 320 } 321 if min := s.Min(); 37 != min { 322 t.Errorf("s.Min(): 37 != %v\n", min) 323 } 324 if max := s.Max(); 9989 != max { 325 t.Errorf("s.Max(): 9989 != %v\n", max) 326 } 327 if mean := s.Mean(); 4748.14 != mean { 328 t.Errorf("s.Mean(): 4748.14 != %v\n", mean) 329 } 330 if stdDev := s.StdDev(); 2826.684117548333 != stdDev { 331 t.Errorf("s.StdDev(): 2826.684117548333 != %v\n", stdDev) 332 } 333 ps := s.Percentiles([]float64{0.5, 0.75, 0.99}) 334 if 4599 != ps[0] { 335 t.Errorf("median: 4599 != %v\n", ps[0]) 336 } 337 if 7380.5 != ps[1] { 338 t.Errorf("75th percentile: 7380.5 != %v\n", ps[1]) 339 } 340 if 9986.429999999998 != ps[2] { 341 t.Errorf("99th percentile: 9986.429999999998 != %v\n", ps[2]) 342 } 343 } 344 345 //testUniformSampleConcurrentUpdateCount将暴露数据争用问题 346 //当用-race调用测试时,对sample的并发更新和计数调用 347 //论点 348 func TestUniformSampleConcurrentUpdateCount(t *testing.T) { 349 if testing.Short() { 350 t.Skip("skipping in short mode") 351 } 352 s := NewUniformSample(100) 353 for i := 0; i < 100; i++ { 354 s.Update(int64(i)) 355 } 356 quit := make(chan struct{}) 357 go func() { 358 t := time.NewTicker(10 * time.Millisecond) 359 for { 360 select { 361 case <-t.C: 362 s.Update(rand.Int63()) 363 case <-quit: 364 t.Stop() 365 return 366 } 367 } 368 }() 369 for i := 0; i < 1000; i++ { 370 s.Count() 371 time.Sleep(5 * time.Millisecond) 372 } 373 quit <- struct{}{} 374 } 375