Commit 81a3f291 authored by Robert Griesemer's avatar Robert Griesemer

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/3920Reviewed-by: 's avatarAlan Donovan <adonovan@google.com>
parent 764a9cf2
...@@ -119,7 +119,7 @@ func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment