]> Cypherpunks repositories - gostls13.git/commitdiff
strconv: simplified logic resulting in faster float formatting
authorRobert Griesemer <gri@golang.org>
Wed, 4 Feb 2015 23:07:04 +0000 (15:07 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 11 Feb 2015 17:45:19 +0000 (17:45 +0000)
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>
src/strconv/ftoa.go

index 1a9c41b85a89d3bb56861bc9a096c17679a7679d..f885d96e9cd73f2f8dfcd4ec92a9831f313c42c0 100644 (file)
@@ -119,7 +119,7 @@ func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
                // Precision for shortest representation mode.
                switch fmt {
                case 'e', 'E':
-                       prec = digs.nd - 1
+                       prec = max(digs.nd-1, 0)
                case 'f':
                        prec = max(digs.nd-digs.dp, 0)
                case 'g', 'G':
@@ -348,14 +348,13 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
        if prec > 0 {
                dst = append(dst, '.')
                i := 1
-               m := d.nd + prec + 1 - max(d.nd, prec+1)
-               for i < m {
-                       dst = append(dst, d.d[i])
-                       i++
+               m := min(d.nd, prec+1)
+               if i < m {
+                       dst = append(dst, d.d[i:m]...)
+                       i = m
                }
-               for i <= prec {
+               for ; i <= prec; i++ {
                        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)
 
-       // dddd
-       var buf [3]byte
-       i := len(buf)
-       for exp >= 10 {
-               i--
-               buf[i] = byte(exp%10 + '0')
-               exp /= 10
+       // dd or ddd
+       switch {
+       case exp < 10:
+               dst = append(dst, '0', byte(exp)+'0')
+       case exp < 100:
+               dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
+       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
 }
 
@@ -406,11 +394,9 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
 
        // integer, padded with zeros as needed.
        if d.dp > 0 {
-               var i int
-               for i = 0; i < d.dp && i < d.nd; i++ {
-                       dst = append(dst, d.d[i])
-               }
-               for ; i < d.dp; i++ {
+               m := min(d.nd, d.dp)
+               dst = append(dst, d.d[:m]...)
+               for ; m < d.dp; m++ {
                        dst = append(dst, '0')
                }
        } else {
@@ -467,6 +453,13 @@ func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
        return append(dst, buf[w:]...)
 }
 
+func min(a, b int) int {
+       if a < b {
+               return a
+       }
+       return b
+}
+
 func max(a, b int) int {
        if a > b {
                return a