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 }