mirror of
https://github.com/golang/go
synced 2024-11-18 16:34:51 -07:00
strconv: simplified logic resulting in faster float formatting
benchmark old ns/op new ns/op delta BenchmarkFormatFloatDecimal 300 283 -5.67% BenchmarkFormatFloat 383 381 -0.52% BenchmarkFormatFloatExp 359 357 -0.56% BenchmarkFormatFloatNegExp 357 358 +0.28% BenchmarkFormatFloatBig 468 430 -8.12% BenchmarkAppendFloatDecimal 104 92.5 -11.06% BenchmarkAppendFloat 199 190 -4.52% BenchmarkAppendFloatExp 172 167 -2.91% BenchmarkAppendFloatNegExp 172 169 -1.74% BenchmarkAppendFloatBig 280 235 -16.07% BenchmarkAppendFloat32Integer 104 92.4 -11.15% BenchmarkAppendFloat32ExactFraction 168 171 +1.79% BenchmarkAppendFloat32Point 206 199 -3.40% BenchmarkAppendFloat32Exp 167 167 +0.00% BenchmarkAppendFloat32NegExp 167 166 -0.60% BenchmarkAppendFloat64Fixed1 134 129 -3.73% BenchmarkAppendFloat64Fixed2 144 136 -5.56% BenchmarkAppendFloat64Fixed3 138 134 -2.90% BenchmarkAppendFloat64Fixed4 145 138 -4.83% Change-Id: Ia143840cb34cbd1cebd6b691dd0a45b7264b406c Reviewed-on: https://go-review.googlesource.com/3920 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
764a9cf20d
commit
81a3f291f0
@ -119,7 +119,7 @@ func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
|
|||||||
// Precision for shortest representation mode.
|
// Precision for shortest representation mode.
|
||||||
switch fmt {
|
switch fmt {
|
||||||
case 'e', 'E':
|
case 'e', 'E':
|
||||||
prec = digs.nd - 1
|
prec = max(digs.nd-1, 0)
|
||||||
case 'f':
|
case 'f':
|
||||||
prec = max(digs.nd-digs.dp, 0)
|
prec = max(digs.nd-digs.dp, 0)
|
||||||
case 'g', 'G':
|
case 'g', 'G':
|
||||||
@ -348,14 +348,13 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
|
|||||||
if prec > 0 {
|
if prec > 0 {
|
||||||
dst = append(dst, '.')
|
dst = append(dst, '.')
|
||||||
i := 1
|
i := 1
|
||||||
m := d.nd + prec + 1 - max(d.nd, prec+1)
|
m := min(d.nd, prec+1)
|
||||||
for i < m {
|
if i < m {
|
||||||
dst = append(dst, d.d[i])
|
dst = append(dst, d.d[i:m]...)
|
||||||
i++
|
i = m
|
||||||
}
|
}
|
||||||
for i <= prec {
|
for ; i <= prec; i++ {
|
||||||
dst = append(dst, '0')
|
dst = append(dst, '0')
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,27 +372,16 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
|
|||||||
}
|
}
|
||||||
dst = append(dst, ch)
|
dst = append(dst, ch)
|
||||||
|
|
||||||
// dddd
|
// dd or ddd
|
||||||
var buf [3]byte
|
switch {
|
||||||
i := len(buf)
|
case exp < 10:
|
||||||
for exp >= 10 {
|
dst = append(dst, '0', byte(exp)+'0')
|
||||||
i--
|
case exp < 100:
|
||||||
buf[i] = byte(exp%10 + '0')
|
dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
|
||||||
exp /= 10
|
default:
|
||||||
|
dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0')
|
||||||
}
|
}
|
||||||
// exp < 10
|
|
||||||
i--
|
|
||||||
buf[i] = byte(exp + '0')
|
|
||||||
|
|
||||||
switch i {
|
|
||||||
case 0:
|
|
||||||
dst = append(dst, buf[0], buf[1], buf[2])
|
|
||||||
case 1:
|
|
||||||
dst = append(dst, buf[1], buf[2])
|
|
||||||
case 2:
|
|
||||||
// leading zeroes
|
|
||||||
dst = append(dst, '0', buf[2])
|
|
||||||
}
|
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,11 +394,9 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
|
|||||||
|
|
||||||
// integer, padded with zeros as needed.
|
// integer, padded with zeros as needed.
|
||||||
if d.dp > 0 {
|
if d.dp > 0 {
|
||||||
var i int
|
m := min(d.nd, d.dp)
|
||||||
for i = 0; i < d.dp && i < d.nd; i++ {
|
dst = append(dst, d.d[:m]...)
|
||||||
dst = append(dst, d.d[i])
|
for ; m < d.dp; m++ {
|
||||||
}
|
|
||||||
for ; i < d.dp; i++ {
|
|
||||||
dst = append(dst, '0')
|
dst = append(dst, '0')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -467,6 +453,13 @@ func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
|
|||||||
return append(dst, buf[w:]...)
|
return append(dst, buf[w:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func min(a, b int) int {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
func max(a, b int) int {
|
func max(a, b int) int {
|
||||||
if a > b {
|
if a > b {
|
||||||
return a
|
return a
|
||||||
|
Loading…
Reference in New Issue
Block a user