math/big: reduce allocations for building decimal strings

Append operations in the decimal String function may cause several allocations.
Use make to pre allocate slices in String that have enough capacity to avoid additional allocations in append operations.

name                 old time/op  new time/op  delta
DecimalConversion-8   139µs ± 7%   109µs ± 2%  -21.06%  (p=0.000 n=10+10)

Change-Id: Id0284d204918a179a0421c51c35d86a3408e1bd9
Reviewed-on: https://go-review.googlesource.com/c/go/+/233980
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Giovanni Bajo <rasky@develer.com>
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Giovanni Bajo <rasky@develer.com>
Trust: Martin Möhrmann <moehrmann@google.com>
This commit is contained in:
surechen 2020-05-15 22:59:38 +08:00 committed by Robert Griesemer
parent f43e012084
commit f588974a52

View File

@ -166,18 +166,21 @@ func (x *decimal) String() string {
switch { switch {
case x.exp <= 0: case x.exp <= 0:
// 0.00ddd // 0.00ddd
buf = make([]byte, 0, 2+(-x.exp)+len(x.mant))
buf = append(buf, "0."...) buf = append(buf, "0."...)
buf = appendZeros(buf, -x.exp) buf = appendZeros(buf, -x.exp)
buf = append(buf, x.mant...) buf = append(buf, x.mant...)
case /* 0 < */ x.exp < len(x.mant): case /* 0 < */ x.exp < len(x.mant):
// dd.ddd // dd.ddd
buf = make([]byte, 0, 1+len(x.mant))
buf = append(buf, x.mant[:x.exp]...) buf = append(buf, x.mant[:x.exp]...)
buf = append(buf, '.') buf = append(buf, '.')
buf = append(buf, x.mant[x.exp:]...) buf = append(buf, x.mant[x.exp:]...)
default: // len(x.mant) <= x.exp default: // len(x.mant) <= x.exp
// ddd00 // ddd00
buf = make([]byte, 0, x.exp)
buf = append(buf, x.mant...) buf = append(buf, x.mant...)
buf = appendZeros(buf, x.exp-len(x.mant)) buf = appendZeros(buf, x.exp-len(x.mant))
} }