@@ -8,6 +8,22 @@ import (
88 "strings"
99)
1010
11+ // Maintain references to common big.Ints to reduce GC pressure
12+ var bigIntLookup = [32 ]* big.Int {}
13+
14+ func init () {
15+ for i := 0 ; i < len (bigIntLookup ); i ++ {
16+ bigIntLookup [i ] = big .NewInt (int64 (i ))
17+ }
18+ }
19+
20+ func cachedBigInt (i int64 ) * big.Int {
21+ if i >= 0 && i < int64 (len (bigIntLookup )) {
22+ return bigIntLookup [i ]
23+ }
24+ return big .NewInt (i )
25+ }
26+
1127// Decimal represents a decimal amount, internally stored as a big.Int.
1228type Decimal struct {
1329 i * big.Int
@@ -26,7 +42,7 @@ func New(i *big.Int, scale int) Decimal {
2642}
2743
2844func NewFromInt64 (i int64 ) Decimal {
29- return New (big . NewInt (i ), 0 )
45+ return New (cachedBigInt (i ), 0 )
3046}
3147
3248// NewFromFloat64 returns a new Decimal with the given scale. The value is
@@ -54,7 +70,7 @@ func NewFromString(s string) (Decimal, error) {
5470
5571// Zero returns a Decimal representing 0, with precision 0.
5672func Zero () Decimal {
57- return New (big . NewInt (0 ), 0 )
73+ return New (cachedBigInt (0 ), 0 )
5874}
5975
6076// MarshalJSON converts the Decimal to JSON bytes.
@@ -109,7 +125,7 @@ func (d Decimal) Float64() float64 {
109125 }
110126
111127 scale := big .NewInt (int64 (d .scale ))
112- scale .Exp (big . NewInt (10 ), scale , nil )
128+ scale .Exp (cachedBigInt (10 ), scale , nil )
113129
114130 r := new (big.Rat )
115131 r .SetFrac (bigIntDefault (d .i ), scale )
@@ -128,7 +144,7 @@ func (d Decimal) ToScale(scale int) Decimal {
128144 exponent = - exponent
129145 }
130146 s := new (big.Int )
131- s .Exp (big . NewInt (10 ), big . NewInt (int64 (exponent )), nil )
147+ s .Exp (cachedBigInt (10 ), cachedBigInt (int64 (exponent )), nil )
132148 di := bigIntDefault (d .i )
133149 o := new (big.Int )
134150 if d .scale > scale {
@@ -179,13 +195,13 @@ func (d Decimal) Sub(y Decimal) Decimal {
179195// MulInt64 multiplies d by y and returns the result. d is left unchanged.
180196func (d Decimal ) MulInt64 (y int64 ) Decimal {
181197 di := bigIntDefault (d .i )
182- return New (new (big.Int ).Mul (di , big . NewInt (y )), d .scale )
198+ return New (new (big.Int ).Mul (di , cachedBigInt (y )), d .scale )
183199}
184200
185201// DivInt64 divides d by y and returns the result. d is left unchanged.
186202func (d Decimal ) DivInt64 (y int64 ) Decimal {
187203 di := bigIntDefault (d .i )
188- return New (new (big.Int ).Div (di , big . NewInt (y )), d .scale )
204+ return New (new (big.Int ).Div (di , cachedBigInt (y )), d .scale )
189205}
190206
191207// Mul multiplies d by y and returns the result. The result has a scale equal to
0 commit comments