github.com/zeebo/mon@v0.0.0-20211012163247-13d39bdb54fa/floathist/histogram_test.go (about)

     1  package floathist
     2  
     3  import (
     4  	"math"
     5  	"sync/atomic"
     6  	"testing"
     7  
     8  	"github.com/zeebo/assert"
     9  	"github.com/zeebo/pcg"
    10  )
    11  
    12  func TestQuantile(t *testing.T) {
    13  	t.Run("Quantile", func(t *testing.T) {
    14  		h := new(Histogram)
    15  		for i := float32(0); i < 1000; i++ {
    16  			h.Observe(i)
    17  		}
    18  
    19  		assert.Equal(t, h.Quantile(0), 0.)
    20  		assert.Equal(t, h.Quantile(.25), 248.)
    21  		assert.Equal(t, h.Quantile(.5), 496.)
    22  		assert.Equal(t, h.Quantile(1), 992.)
    23  	})
    24  
    25  	t.Run("CDF", func(t *testing.T) {
    26  		h := new(Histogram)
    27  		for i := float32(0); i < 1000; i++ {
    28  			h.Observe(i)
    29  		}
    30  
    31  		assert.Equal(t, h.CDF(0), 0.001)
    32  		assert.Equal(t, h.CDF(250), 0.252)
    33  		assert.Equal(t, h.CDF(500), 0.504)
    34  		assert.Equal(t, h.CDF(1000), 1.0)
    35  	})
    36  
    37  	t.Run("Sum", func(t *testing.T) {
    38  		h := new(Histogram)
    39  		rsum := float32(0)
    40  		for i := float32(0); i < 1000; i++ {
    41  			h.Observe(i)
    42  			rsum += i
    43  		}
    44  
    45  		assert.Equal(t, h.Sum(), 499978.6640625) // 499500
    46  	})
    47  
    48  	t.Run("Average", func(t *testing.T) {
    49  		h := new(Histogram)
    50  		rsum := float32(0)
    51  		for i := float32(0); i < 1000; i++ {
    52  			h.Observe(i)
    53  			rsum += i
    54  		}
    55  
    56  		sum, avg := h.Average()
    57  
    58  		assert.Equal(t, sum, 499978.6640625) // 499500
    59  		assert.Equal(t, avg, 499.9786640625) // 499.5
    60  	})
    61  
    62  	t.Run("Variance", func(t *testing.T) {
    63  		h := new(Histogram)
    64  		rsum := float32(0)
    65  		for i := float32(0); i < 1000; i++ {
    66  			h.Observe(i)
    67  			rsum += i
    68  		}
    69  
    70  		sum, avg, vari := h.Variance()
    71  
    72  		assert.Equal(t, sum, 499978.6640625)   // 499500
    73  		assert.Equal(t, avg, 499.9786640625)   // 499.5
    74  		assert.Equal(t, vari, 83433.942757616) // 83416.667
    75  	})
    76  }
    77  
    78  func BenchmarkHistogram(b *testing.B) {
    79  	b.Run("Observe", func(b *testing.B) {
    80  		his := new(Histogram)
    81  
    82  		for i := 0; i < b.N; i++ {
    83  			his.Observe(1)
    84  		}
    85  	})
    86  
    87  	b.Run("Observe_Parallel", func(b *testing.B) {
    88  		his := new(Histogram)
    89  		n := int64(0)
    90  		b.RunParallel(func(pb *testing.PB) {
    91  			i := float32(uint64(1024) << uint64(atomic.AddInt64(&n, 1)))
    92  			for pb.Next() {
    93  				his.Observe(i)
    94  			}
    95  		})
    96  	})
    97  
    98  	b.Run("Total", func(b *testing.B) {
    99  		his := new(Histogram)
   100  		for i := 0; i < 1000000; i++ {
   101  			his.Observe(pcg.Float32())
   102  		}
   103  		b.ReportAllocs()
   104  		b.ResetTimer()
   105  
   106  		for i := 0; i < b.N; i++ {
   107  			his.Total()
   108  		}
   109  	})
   110  
   111  	b.Run("Total_Easy", func(b *testing.B) {
   112  		his := new(Histogram)
   113  		for i := 0; i < 1000000; i++ {
   114  			his.Observe(math.Float32frombits(pcg.Uint32() &^ ((1<<10 - 1) << 22)))
   115  		}
   116  		assert.Equal(b, his.Total(), 1000000)
   117  		b.ReportAllocs()
   118  		b.ResetTimer()
   119  
   120  		for i := 0; i < b.N; i++ {
   121  			his.Total()
   122  		}
   123  	})
   124  
   125  	b.Run("Quantile", func(b *testing.B) {
   126  		his := new(Histogram)
   127  		for i := 0; i < 1000000; i++ {
   128  			his.Observe(pcg.Float32())
   129  		}
   130  		assert.Equal(b, his.Total(), 1000000)
   131  		b.ReportAllocs()
   132  		b.ResetTimer()
   133  
   134  		for i := 0; i < b.N; i++ {
   135  			his.Quantile(pcg.Float64())
   136  		}
   137  	})
   138  
   139  	b.Run("Quantile_Easy", func(b *testing.B) {
   140  		his := new(Histogram)
   141  		for i := 0; i < 1000000; i++ {
   142  			his.Observe(math.Float32frombits(pcg.Uint32() &^ ((1<<10 - 1) << 22)))
   143  		}
   144  		assert.Equal(b, his.Total(), 1000000)
   145  		b.ReportAllocs()
   146  		b.ResetTimer()
   147  
   148  		for i := 0; i < b.N; i++ {
   149  			his.Quantile(pcg.Float64())
   150  		}
   151  	})
   152  
   153  	b.Run("CDF", func(b *testing.B) {
   154  		his := new(Histogram)
   155  		for i := 0; i < 1000000; i++ {
   156  			his.Observe(pcg.Float32())
   157  		}
   158  		assert.Equal(b, his.Total(), 1000000)
   159  		b.ReportAllocs()
   160  		b.ResetTimer()
   161  
   162  		for i := 0; i < b.N; i++ {
   163  			his.CDF(pcg.Float32())
   164  		}
   165  	})
   166  
   167  	b.Run("CDF_Easy", func(b *testing.B) {
   168  		his := new(Histogram)
   169  		for i := 0; i < 1000000; i++ {
   170  			his.Observe(math.Float32frombits(pcg.Uint32() &^ ((1<<10 - 1) << 22)))
   171  		}
   172  		assert.Equal(b, his.Total(), 1000000)
   173  		b.ReportAllocs()
   174  		b.ResetTimer()
   175  
   176  		for i := 0; i < b.N; i++ {
   177  			his.CDF(pcg.Float32())
   178  		}
   179  	})
   180  
   181  	b.Run("Sum", func(b *testing.B) {
   182  		his := new(Histogram)
   183  		for i := 0; i < 1000; i++ {
   184  			his.Observe(pcg.Float32())
   185  		}
   186  		assert.Equal(b, his.Total(), 1000)
   187  		b.ReportAllocs()
   188  		b.ResetTimer()
   189  
   190  		for i := 0; i < b.N; i++ {
   191  			_ = his.Sum()
   192  		}
   193  	})
   194  
   195  	b.Run("Average", func(b *testing.B) {
   196  		his := new(Histogram)
   197  		for i := 0; i < 1000; i++ {
   198  			his.Observe(pcg.Float32())
   199  		}
   200  		assert.Equal(b, his.Total(), 1000)
   201  		b.ReportAllocs()
   202  		b.ResetTimer()
   203  
   204  		for i := 0; i < b.N; i++ {
   205  			_, _ = his.Average()
   206  		}
   207  	})
   208  
   209  	b.Run("Variance", func(b *testing.B) {
   210  		his := new(Histogram)
   211  		for i := 0; i < 1000; i++ {
   212  			his.Observe(pcg.Float32())
   213  		}
   214  		assert.Equal(b, his.Total(), 1000)
   215  		b.ReportAllocs()
   216  		b.ResetTimer()
   217  
   218  		for i := 0; i < b.N; i++ {
   219  			_, _, _ = his.Variance()
   220  		}
   221  	})
   222  }