decimal_bench_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package decimal
  2. import (
  3. "fmt"
  4. "math"
  5. "math/rand"
  6. "sort"
  7. "strconv"
  8. "testing"
  9. )
  10. type DecimalSlice []Decimal
  11. func (p DecimalSlice) Len() int { return len(p) }
  12. func (p DecimalSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  13. func (p DecimalSlice) Less(i, j int) bool { return p[i].Cmp(p[j]) < 0 }
  14. func BenchmarkNewFromFloatWithExponent(b *testing.B) {
  15. rng := rand.New(rand.NewSource(0xdead1337))
  16. in := make([]float64, b.N)
  17. for i := range in {
  18. in[i] = rng.NormFloat64() * 10e20
  19. }
  20. b.ReportAllocs()
  21. b.StartTimer()
  22. for i := 0; i < b.N; i++ {
  23. in := rng.NormFloat64() * 10e20
  24. _ = NewFromFloatWithExponent(in, math.MinInt32)
  25. }
  26. }
  27. func BenchmarkNewFromFloat(b *testing.B) {
  28. rng := rand.New(rand.NewSource(0xdead1337))
  29. in := make([]float64, b.N)
  30. for i := range in {
  31. in[i] = rng.NormFloat64() * 10e20
  32. }
  33. b.ReportAllocs()
  34. b.StartTimer()
  35. for i := 0; i < b.N; i++ {
  36. _ = NewFromFloat(in[i])
  37. }
  38. }
  39. func BenchmarkNewFromStringFloat(b *testing.B) {
  40. rng := rand.New(rand.NewSource(0xdead1337))
  41. in := make([]float64, b.N)
  42. for i := range in {
  43. in[i] = rng.NormFloat64() * 10e20
  44. }
  45. b.ReportAllocs()
  46. b.StartTimer()
  47. for i := 0; i < b.N; i++ {
  48. in := strconv.FormatFloat(in[i], 'f', -1, 64)
  49. _, _ = NewFromString(in)
  50. }
  51. }
  52. func Benchmark_FloorFast(b *testing.B) {
  53. input := New(200, 2)
  54. b.ResetTimer()
  55. for i := 0; i < b.N; i++ {
  56. input.Floor()
  57. }
  58. }
  59. func Benchmark_FloorRegular(b *testing.B) {
  60. input := New(200, -2)
  61. b.ResetTimer()
  62. for i := 0; i < b.N; i++ {
  63. input.Floor()
  64. }
  65. }
  66. func Benchmark_DivideOriginal(b *testing.B) {
  67. tcs := createDivTestCases()
  68. b.ResetTimer()
  69. for i := 0; i < b.N; i++ {
  70. for _, tc := range tcs {
  71. d := tc.d
  72. if sign(tc.d2) == 0 {
  73. continue
  74. }
  75. d2 := tc.d2
  76. prec := tc.prec
  77. a := d.DivOld(d2, int(prec))
  78. if sign(a) > 2 {
  79. panic("dummy panic")
  80. }
  81. }
  82. }
  83. }
  84. func Benchmark_DivideNew(b *testing.B) {
  85. tcs := createDivTestCases()
  86. b.ResetTimer()
  87. for i := 0; i < b.N; i++ {
  88. for _, tc := range tcs {
  89. d := tc.d
  90. if sign(tc.d2) == 0 {
  91. continue
  92. }
  93. d2 := tc.d2
  94. prec := tc.prec
  95. a := d.DivRound(d2, prec)
  96. if sign(a) > 2 {
  97. panic("dummy panic")
  98. }
  99. }
  100. }
  101. }
  102. func BenchmarkDecimal_RoundCash_Five(b *testing.B) {
  103. const want = "3.50"
  104. for i := 0; i < b.N; i++ {
  105. val := New(3478, -3)
  106. if have := val.StringFixedCash(5); have != want {
  107. b.Fatalf("\nHave: %q\nWant: %q", have, want)
  108. }
  109. }
  110. }
  111. func Benchmark_Cmp(b *testing.B) {
  112. decimals := DecimalSlice([]Decimal{})
  113. for i := 0; i < 1000000; i++ {
  114. decimals = append(decimals, New(int64(i), 0))
  115. }
  116. b.ResetTimer()
  117. for i := 0; i < b.N; i++ {
  118. sort.Sort(decimals)
  119. }
  120. }
  121. func Benchmark_decimal_Decimal_Add_different_precision(b *testing.B) {
  122. d1 := NewFromFloat(1000.123)
  123. d2 := NewFromFloat(500).Mul(NewFromFloat(0.12))
  124. b.ReportAllocs()
  125. b.StartTimer()
  126. for i := 0; i < b.N; i++ {
  127. d1.Add(d2)
  128. }
  129. }
  130. func Benchmark_decimal_Decimal_Sub_different_precision(b *testing.B) {
  131. d1 := NewFromFloat(1000.123)
  132. d2 := NewFromFloat(500).Mul(NewFromFloat(0.12))
  133. b.ReportAllocs()
  134. b.StartTimer()
  135. for i := 0; i < b.N; i++ {
  136. d1.Sub(d2)
  137. }
  138. }
  139. func Benchmark_decimal_Decimal_Add_same_precision(b *testing.B) {
  140. d1 := NewFromFloat(1000.123)
  141. d2 := NewFromFloat(500.123)
  142. b.ReportAllocs()
  143. b.StartTimer()
  144. for i := 0; i < b.N; i++ {
  145. d1.Add(d2)
  146. }
  147. }
  148. func Benchmark_decimal_Decimal_Sub_same_precision(b *testing.B) {
  149. d1 := NewFromFloat(1000.123)
  150. d2 := NewFromFloat(500.123)
  151. b.ReportAllocs()
  152. b.StartTimer()
  153. for i := 0; i < b.N; i++ {
  154. d1.Add(d2)
  155. }
  156. }
  157. func BenchmarkDecimal_IsInteger(b *testing.B) {
  158. d := RequireFromString("12.000")
  159. b.ReportAllocs()
  160. b.StartTimer()
  161. for i := 0; i < b.N; i++ {
  162. d.IsInteger()
  163. }
  164. }
  165. func BenchmarkDecimal_NewFromString(b *testing.B) {
  166. count := 72
  167. prices := make([]string, 0, count)
  168. for i := 1; i <= count; i++ {
  169. prices = append(prices, fmt.Sprintf("%d.%d", i*100, i))
  170. }
  171. b.ReportAllocs()
  172. b.ResetTimer()
  173. for i := 0; i < b.N; i++ {
  174. for _, p := range prices {
  175. d, err := NewFromString(p)
  176. if err != nil {
  177. b.Log(d)
  178. b.Error(err)
  179. }
  180. }
  181. }
  182. }
  183. func BenchmarkDecimal_NewFromString_large_number(b *testing.B) {
  184. count := 72
  185. prices := make([]string, 0, count)
  186. for i := 1; i <= count; i++ {
  187. prices = append(prices, "9323372036854775807.9223372036854775807")
  188. }
  189. b.ReportAllocs()
  190. b.ResetTimer()
  191. for i := 0; i < b.N; i++ {
  192. for _, p := range prices {
  193. d, err := NewFromString(p)
  194. if err != nil {
  195. b.Log(d)
  196. b.Error(err)
  197. }
  198. }
  199. }
  200. }