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