1 package decimal
2
3 import (
4 "fmt"
5 "math"
6 "math/big"
7 "math/rand"
8 "sort"
9 "strconv"
10 "testing"
11 )
12
13 type DecimalSlice []Decimal
14
15 func (p DecimalSlice) Len() int { return len(p) }
16 func (p DecimalSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
17 func (p DecimalSlice) Less(i, j int) bool { return p[i].Cmp(p[j]) < 0 }
18
19 func BenchmarkNewFromFloatWithExponent(b *testing.B) {
20 rng := rand.New(rand.NewSource(0xdead1337))
21 in := make([]float64, b.N)
22 for i := range in {
23 in[i] = rng.NormFloat64() * 10e20
24 }
25 b.ReportAllocs()
26 b.StartTimer()
27 for i := 0; i < b.N; i++ {
28 in := rng.NormFloat64() * 10e20
29 _ = NewFromFloatWithExponent(in, math.MinInt32)
30 }
31 }
32
33 func BenchmarkNewFromFloat(b *testing.B) {
34 rng := rand.New(rand.NewSource(0xdead1337))
35 in := make([]float64, b.N)
36 for i := range in {
37 in[i] = rng.NormFloat64() * 10e20
38 }
39 b.ReportAllocs()
40 b.StartTimer()
41 for i := 0; i < b.N; i++ {
42 _ = NewFromFloat(in[i])
43 }
44 }
45
46 func BenchmarkNewFromStringFloat(b *testing.B) {
47 rng := rand.New(rand.NewSource(0xdead1337))
48 in := make([]float64, b.N)
49 for i := range in {
50 in[i] = rng.NormFloat64() * 10e20
51 }
52 b.ReportAllocs()
53 b.StartTimer()
54 for i := 0; i < b.N; i++ {
55 in := strconv.FormatFloat(in[i], 'f', -1, 64)
56 _, _ = NewFromString(in)
57 }
58 }
59
60 func Benchmark_FloorFast(b *testing.B) {
61 input := New(200, 2)
62 b.ResetTimer()
63 for i := 0; i < b.N; i++ {
64 input.Floor()
65 }
66 }
67
68 func Benchmark_FloorRegular(b *testing.B) {
69 input := New(200, -2)
70 b.ResetTimer()
71 for i := 0; i < b.N; i++ {
72 input.Floor()
73 }
74 }
75
76 func Benchmark_DivideOriginal(b *testing.B) {
77 tcs := createDivTestCases()
78 b.ResetTimer()
79 for i := 0; i < b.N; i++ {
80 for _, tc := range tcs {
81 d := tc.d
82 if sign(tc.d2) == 0 {
83 continue
84 }
85 d2 := tc.d2
86 prec := tc.prec
87 a := d.DivOld(d2, int(prec))
88 if sign(a) > 2 {
89 panic("dummy panic")
90 }
91 }
92 }
93 }
94
95 func Benchmark_DivideNew(b *testing.B) {
96 tcs := createDivTestCases()
97 b.ResetTimer()
98 for i := 0; i < b.N; i++ {
99 for _, tc := range tcs {
100 d := tc.d
101 if sign(tc.d2) == 0 {
102 continue
103 }
104 d2 := tc.d2
105 prec := tc.prec
106 a := d.DivRound(d2, prec)
107 if sign(a) > 2 {
108 panic("dummy panic")
109 }
110 }
111 }
112 }
113
114 func BenchmarkDecimal_RoundCash_Five(b *testing.B) {
115 const want = "3.50"
116 for i := 0; i < b.N; i++ {
117 val := New(3478, -3)
118 if have := val.StringFixedCash(5); have != want {
119 b.Fatalf("\nHave: %q\nWant: %q", have, want)
120 }
121 }
122 }
123
124 func numDigits(b *testing.B, want int, val Decimal) {
125 b.Helper()
126 for i := 0; i < b.N; i++ {
127 if have := val.NumDigits(); have != want {
128 b.Fatalf("\nHave: %d\nWant: %d", have, want)
129 }
130 }
131 }
132
133 func BenchmarkDecimal_NumDigits10(b *testing.B) {
134 numDigits(b, 10, New(3478512345, -3))
135 }
136
137 func BenchmarkDecimal_NumDigits100(b *testing.B) {
138 s := make([]byte, 102)
139 for i := range s {
140 s[i] = byte('0' + i%10)
141 }
142 s[0] = '-'
143 s[100] = '.'
144 d, err := NewFromString(string(s))
145 if err != nil {
146 b.Log(d)
147 b.Error(err)
148 }
149 numDigits(b, 100, d)
150 }
151
152 func Benchmark_Cmp(b *testing.B) {
153 decimals := DecimalSlice([]Decimal{})
154 for i := 0; i < 1000000; i++ {
155 decimals = append(decimals, New(int64(i), 0))
156 }
157 b.ResetTimer()
158 for i := 0; i < b.N; i++ {
159 sort.Sort(decimals)
160 }
161 }
162
163 func BenchmarkDecimal_Add_different_precision(b *testing.B) {
164 d1 := NewFromFloat(1000.123)
165 d2 := NewFromFloat(500).Mul(NewFromFloat(0.12))
166
167 b.ReportAllocs()
168 b.StartTimer()
169 for i := 0; i < b.N; i++ {
170 d1.Add(d2)
171 }
172 }
173
174 func BenchmarkDecimal_Sub_different_precision(b *testing.B) {
175 d1 := NewFromFloat(1000.123)
176 d2 := NewFromFloat(500).Mul(NewFromFloat(0.12))
177
178 b.ReportAllocs()
179 b.StartTimer()
180 for i := 0; i < b.N; i++ {
181 d1.Sub(d2)
182 }
183 }
184
185 func BenchmarkDecimal_Add_same_precision(b *testing.B) {
186 d1 := NewFromFloat(1000.123)
187 d2 := NewFromFloat(500.123)
188
189 b.ReportAllocs()
190 b.StartTimer()
191 for i := 0; i < b.N; i++ {
192 d1.Add(d2)
193 }
194 }
195
196 func BenchmarkDecimal_Sub_same_precision(b *testing.B) {
197 d1 := NewFromFloat(1000.123)
198 d2 := NewFromFloat(500.123)
199
200 b.ReportAllocs()
201 b.StartTimer()
202 for i := 0; i < b.N; i++ {
203 d1.Add(d2)
204 }
205 }
206
207 func BenchmarkDecimal_IsInteger(b *testing.B) {
208 d := RequireFromString("12.000")
209
210 b.ReportAllocs()
211 b.StartTimer()
212 for i := 0; i < b.N; i++ {
213 d.IsInteger()
214 }
215 }
216
217 func BenchmarkDecimal_Pow(b *testing.B) {
218 d1 := RequireFromString("5.2")
219 d2 := RequireFromString("6.3")
220
221 for i := 0; i < b.N; i++ {
222 d1.Pow(d2)
223 }
224 }
225
226 func BenchmarkDecimal_PowWithPrecision(b *testing.B) {
227 d1 := RequireFromString("5.2")
228 d2 := RequireFromString("6.3")
229
230 for i := 0; i < b.N; i++ {
231 _, _ = d1.PowWithPrecision(d2, 8)
232 }
233 }
234 func BenchmarkDecimal_PowInt32(b *testing.B) {
235 d1 := RequireFromString("5.2")
236 d2 := int32(10)
237
238 for i := 0; i < b.N; i++ {
239 _, _ = d1.PowInt32(d2)
240 }
241 }
242
243 func BenchmarkDecimal_PowBigInt(b *testing.B) {
244 d1 := RequireFromString("5.2")
245 d2 := big.NewInt(10)
246
247 for i := 0; i < b.N; i++ {
248 _, _ = d1.PowBigInt(d2)
249 }
250 }
251
252 func BenchmarkDecimal_NewFromString(b *testing.B) {
253 count := 72
254 prices := make([]string, 0, count)
255 for i := 1; i <= count; i++ {
256 prices = append(prices, fmt.Sprintf("%d.%d", i*100, i))
257 }
258
259 b.ReportAllocs()
260 b.ResetTimer()
261 for i := 0; i < b.N; i++ {
262 for _, p := range prices {
263 d, err := NewFromString(p)
264 if err != nil {
265 b.Log(d)
266 b.Error(err)
267 }
268 }
269 }
270 }
271
272 func BenchmarkDecimal_NewFromString_large_number(b *testing.B) {
273 count := 72
274 prices := make([]string, 0, count)
275 for i := 1; i <= count; i++ {
276 prices = append(prices, "9323372036854775807.9223372036854775807")
277 }
278
279 b.ReportAllocs()
280 b.ResetTimer()
281 for i := 0; i < b.N; i++ {
282 for _, p := range prices {
283 d, err := NewFromString(p)
284 if err != nil {
285 b.Log(d)
286 b.Error(err)
287 }
288 }
289 }
290 }
291
292 func BenchmarkDecimal_ExpHullAbraham(b *testing.B) {
293 b.ResetTimer()
294
295 d := RequireFromString("30.412346346346")
296
297 b.ReportAllocs()
298 b.ResetTimer()
299 for i := 0; i < b.N; i++ {
300 _, _ = d.ExpHullAbrham(10)
301 }
302 }
303
304 func BenchmarkDecimal_ExpTaylor(b *testing.B) {
305 b.ResetTimer()
306
307 d := RequireFromString("30.412346346346")
308
309 b.ReportAllocs()
310 b.ResetTimer()
311 for i := 0; i < b.N; i++ {
312 _, _ = d.ExpTaylor(10)
313 }
314 }
315
View as plain text