sample_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package metrics
  2. import (
  3. "math/rand"
  4. "runtime"
  5. "testing"
  6. "time"
  7. )
  8. func BenchmarkExpDecaySample257(b *testing.B) {
  9. benchmarkSample(b, NewExpDecaySample(257, 0.015))
  10. }
  11. func BenchmarkExpDecaySample514(b *testing.B) {
  12. benchmarkSample(b, NewExpDecaySample(514, 0.015))
  13. }
  14. func BenchmarkExpDecaySample1028(b *testing.B) {
  15. benchmarkSample(b, NewExpDecaySample(1028, 0.015))
  16. }
  17. func BenchmarkUniformSample257(b *testing.B) {
  18. benchmarkSample(b, NewUniformSample(257))
  19. }
  20. func BenchmarkUniformSample514(b *testing.B) {
  21. benchmarkSample(b, NewUniformSample(514))
  22. }
  23. func BenchmarkUniformSample1028(b *testing.B) {
  24. benchmarkSample(b, NewUniformSample(1028))
  25. }
  26. func TestExpDecaySample10(t *testing.T) {
  27. rand.Seed(1)
  28. s := NewExpDecaySample(100, 0.99)
  29. for i := 0; i < 10; i++ {
  30. s.Update(int64(i))
  31. }
  32. if size := s.Count(); 10 != size {
  33. t.Errorf("s.Count(): 10 != %v\n", size)
  34. }
  35. if size := s.Size(); 10 != size {
  36. t.Errorf("s.Size(): 10 != %v\n", size)
  37. }
  38. if l := len(s.Values()); 10 != l {
  39. t.Errorf("len(s.Values()): 10 != %v\n", l)
  40. }
  41. for _, v := range s.Values() {
  42. if v > 10 || v < 0 {
  43. t.Errorf("out of range [0, 10): %v\n", v)
  44. }
  45. }
  46. }
  47. func TestExpDecaySample100(t *testing.T) {
  48. rand.Seed(1)
  49. s := NewExpDecaySample(1000, 0.01)
  50. for i := 0; i < 100; i++ {
  51. s.Update(int64(i))
  52. }
  53. if size := s.Count(); 100 != size {
  54. t.Errorf("s.Count(): 100 != %v\n", size)
  55. }
  56. if size := s.Size(); 100 != size {
  57. t.Errorf("s.Size(): 100 != %v\n", size)
  58. }
  59. if l := len(s.Values()); 100 != l {
  60. t.Errorf("len(s.Values()): 100 != %v\n", l)
  61. }
  62. for _, v := range s.Values() {
  63. if v > 100 || v < 0 {
  64. t.Errorf("out of range [0, 100): %v\n", v)
  65. }
  66. }
  67. }
  68. func TestExpDecaySample1000(t *testing.T) {
  69. rand.Seed(1)
  70. s := NewExpDecaySample(100, 0.99)
  71. for i := 0; i < 1000; i++ {
  72. s.Update(int64(i))
  73. }
  74. if size := s.Count(); 1000 != size {
  75. t.Errorf("s.Count(): 1000 != %v\n", size)
  76. }
  77. if size := s.Size(); 100 != size {
  78. t.Errorf("s.Size(): 100 != %v\n", size)
  79. }
  80. if l := len(s.Values()); 100 != l {
  81. t.Errorf("len(s.Values()): 100 != %v\n", l)
  82. }
  83. for _, v := range s.Values() {
  84. if v > 1000 || v < 0 {
  85. t.Errorf("out of range [0, 1000): %v\n", v)
  86. }
  87. }
  88. }
  89. func TestExpDecaySampleDup(t *testing.T) {
  90. s1 := NewExpDecaySample(100, 0.99)
  91. s1.Update(1)
  92. s2 := s1.Dup()
  93. s1.Update(1)
  94. if 1 != s2.Size() {
  95. t.Fatal(s2)
  96. }
  97. }
  98. // This test makes sure that the sample's priority is not amplified by using
  99. // nanosecond duration since start rather than second duration since start.
  100. // The priority becomes +Inf quickly after starting if this is done,
  101. // effectively freezing the set of samples until a rescale step happens.
  102. func TestExpDecaySampleNanosecondRegression(t *testing.T) {
  103. rand.Seed(1)
  104. s := NewExpDecaySample(100, 0.99)
  105. for i := 0; i < 100; i++ {
  106. s.Update(10)
  107. }
  108. time.Sleep(1 * time.Millisecond)
  109. for i := 0; i < 100; i++ {
  110. s.Update(20)
  111. }
  112. v := s.Values()
  113. avg := float64(0)
  114. for i := 0; i < len(v); i++ {
  115. avg += float64(v[i])
  116. }
  117. avg /= float64(len(v))
  118. if avg > 16 || avg < 14 {
  119. t.Errorf("out of range [14, 16]: %v\n", avg)
  120. }
  121. }
  122. func TestExpDecaySampleStatistics(t *testing.T) {
  123. now := time.Now()
  124. rand.Seed(1)
  125. s := NewExpDecaySample(100, 0.99)
  126. for i := 1; i <= 10000; i++ {
  127. s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
  128. }
  129. if count := s.Count(); 10000 != count {
  130. t.Errorf("s.Count(): 10000 != %v\n", count)
  131. }
  132. if min := s.Min(); 107 != min {
  133. t.Errorf("s.Min(): 107 != %v\n", min)
  134. }
  135. if max := s.Max(); 10000 != max {
  136. t.Errorf("s.Max(): 10000 != %v\n", max)
  137. }
  138. if mean := s.Mean(); 4965.98 != mean {
  139. t.Errorf("s.Mean(): 4965.98 != %v\n", mean)
  140. }
  141. if stdDev := s.StdDev(); 2959.825156930727 != stdDev {
  142. t.Errorf("s.StdDev(): 2959.825156930727 != %v\n", stdDev)
  143. }
  144. ps := s.Percentiles([]float64{0.5, 0.75, 0.99})
  145. if 4615 != ps[0] {
  146. t.Errorf("median: 4615 != %v\n", ps[0])
  147. }
  148. if 7672 != ps[1] {
  149. t.Errorf("75th percentile: 7672 != %v\n", ps[1])
  150. }
  151. if 9998.99 != ps[2] {
  152. t.Errorf("99th percentile: 9998.99 != %v\n", ps[2])
  153. }
  154. }
  155. func TestUniformSample(t *testing.T) {
  156. rand.Seed(1)
  157. s := NewUniformSample(100)
  158. for i := 0; i < 1000; i++ {
  159. s.Update(int64(i))
  160. }
  161. if size := s.Count(); 1000 != size {
  162. t.Errorf("s.Count(): 1000 != %v\n", size)
  163. }
  164. if size := s.Size(); 100 != size {
  165. t.Errorf("s.Size(): 100 != %v\n", size)
  166. }
  167. if l := len(s.Values()); 100 != l {
  168. t.Errorf("len(s.Values()): 100 != %v\n", l)
  169. }
  170. for _, v := range s.Values() {
  171. if v > 1000 || v < 0 {
  172. t.Errorf("out of range [0, 100): %v\n", v)
  173. }
  174. }
  175. }
  176. func TestUniformSampleDup(t *testing.T) {
  177. s1 := NewUniformSample(100)
  178. s1.Update(1)
  179. s2 := s1.Dup()
  180. s1.Update(1)
  181. if 1 != s2.Size() {
  182. t.Fatal(s2)
  183. }
  184. }
  185. func TestUniformSampleIncludesTail(t *testing.T) {
  186. rand.Seed(1)
  187. s := NewUniformSample(100)
  188. max := 100
  189. for i := 0; i < max; i++ {
  190. s.Update(int64(i))
  191. }
  192. v := s.Values()
  193. sum := 0
  194. exp := (max - 1) * max / 2
  195. for i := 0; i < len(v); i++ {
  196. sum += int(v[i])
  197. }
  198. if exp != sum {
  199. t.Errorf("sum: %v != %v\n", exp, sum)
  200. }
  201. }
  202. func TestUniformSampleStatistics(t *testing.T) {
  203. rand.Seed(1)
  204. s := NewUniformSample(100)
  205. for i := 1; i <= 10000; i++ {
  206. s.Update(int64(i))
  207. }
  208. if count := s.Count(); 10000 != count {
  209. t.Errorf("s.Count(): 10000 != %v\n", count)
  210. }
  211. if min := s.Min(); 9412 != min {
  212. t.Errorf("s.Min(): 9412 != %v\n", min)
  213. }
  214. if max := s.Max(); 10000 != max {
  215. t.Errorf("s.Max(): 10000 != %v\n", max)
  216. }
  217. if mean := s.Mean(); 9902.26 != mean {
  218. t.Errorf("s.Mean(): 9902.26 != %v\n", mean)
  219. }
  220. if stdDev := s.StdDev(); 101.8667384380201 != stdDev {
  221. t.Errorf("s.StdDev(): 101.8667384380201 != %v\n", stdDev)
  222. }
  223. ps := s.Percentiles([]float64{0.5, 0.75, 0.99})
  224. if 9930.5 != ps[0] {
  225. t.Errorf("median: 9930.5 != %v\n", ps[0])
  226. }
  227. if 9973.75 != ps[1] {
  228. t.Errorf("75th percentile: 9973.75 != %v\n", ps[1])
  229. }
  230. if 9999.99 != ps[2] {
  231. t.Errorf("99th percentile: 9999.99 != %v\n", ps[2])
  232. }
  233. }
  234. func benchmarkSample(b *testing.B, s Sample) {
  235. var memStats runtime.MemStats
  236. runtime.ReadMemStats(&memStats)
  237. pauseTotalNs := memStats.PauseTotalNs
  238. b.ResetTimer()
  239. for i := 0; i < b.N; i++ {
  240. s.Update(1)
  241. }
  242. b.StopTimer()
  243. runtime.GC()
  244. runtime.ReadMemStats(&memStats)
  245. b.Logf("GC cost: %d ns/op", int(memStats.PauseTotalNs-pauseTotalNs)/b.N)
  246. }