github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/metrics/sample_test.go (about)

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