]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: factored out an internal accessor method (cleanup), added benchmark
authorRobert Griesemer <gri@golang.org>
Wed, 23 Sep 2015 17:05:44 +0000 (10:05 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 23 Sep 2015 20:25:59 +0000 (20:25 +0000)
Current result of DecimalConversion benchmark (for future reference):

BenchmarkDecimalConversion-8    10000     204770 ns/op

Measured on Mac Mini (late 2012) running OS X 10.10.5,
2.3 GHz Intel Core i7, 8 GB 1333 MHz DDR3.

Also: Removed comment suggesting to implement decimal by representing
digits as numbers 0..9 rather than ASCII chars '0'..'9' to avoid
repeated +/-'0' operations. Tried and it appears (per above benchmark)
that the +/-'0' operations are neglibile but the addition conversion
passes around it are not and that it makes things significantly slower.

Change-Id: I6ee033b1172043248093cc5d02abff5fc54c2e7a
Reviewed-on: https://go-review.googlesource.com/14857
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
src/math/big/decimal.go
src/math/big/decimal_test.go
src/math/big/ftoa.go

index 7789677f76b915ea4059d9aecd082ac444ce1d0b..b9e181dba3f3aab96faafabc31d3f6d65b5647eb 100644 (file)
@@ -29,6 +29,14 @@ type decimal struct {
        exp  int    // exponent
 }
 
+// at returns the i'th mantissa digit, starting with the most significant digit at 0.
+func (d *decimal) at(i int) byte {
+       if 0 <= i && i < len(d.mant) {
+               return d.mant[i]
+       }
+       return '0'
+}
+
 // Maximum shift amount that can be done in one pass without overflow.
 // A Word has _W bits and (1<<maxShift - 1)*10 + 9 must fit into Word.
 const maxShift = _W - 4
@@ -92,12 +100,6 @@ func (x *decimal) init(m nat, shift int) {
        }
 }
 
-// Possibly optimization: The current implementation of nat.string takes
-// a charset argument. When a right shift is needed, we could provide
-// "\x00\x01...\x09" instead of "012..9" (as in nat.decimalString) and
-// avoid the repeated +'0' and -'0' operations in decimal.shr (and do a
-// single +'0' pass at the end).
-
 // shr implements x >> s, for s <= maxShift.
 func shr(x *decimal, s uint) {
        // Division by 1<<s using shift-and-subtract algorithm.
index 81e022a47dd60848e06cf8b802ce7e8979520f9e..15bdb181e725742bca198443dc720aaa3f06a0e0 100644 (file)
@@ -104,3 +104,13 @@ func TestDecimalRounding(t *testing.T) {
                }
        }
 }
+
+func BenchmarkDecimalConversion(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               for shift := -100; shift <= +100; shift++ {
+                       var d decimal
+                       d.init(natOne, shift)
+                       d.String()
+               }
+       }
+}
index 21d5b546ff64455b86bbc43857caf3568f55e9a8..5c1d31ebde3032845b0dae81bc01a7cc94aa4873 100644 (file)
@@ -201,14 +201,8 @@ func roundShortest(d *decimal, x *Float) {
        // Now we can figure out the minimum number of digits required.
        // Walk along until d has distinguished itself from upper and lower.
        for i, m := range d.mant {
-               l := byte('0') // lower digit
-               if i < len(lower.mant) {
-                       l = lower.mant[i]
-               }
-               u := byte('0') // upper digit
-               if i < len(upper.mant) {
-                       u = upper.mant[i]
-               }
+               l := lower.at(i)
+               u := upper.at(i)
 
                // Okay to round down (truncate) if lower has a different digit
                // or if lower is inclusive and is exactly the result of rounding
@@ -296,11 +290,7 @@ func fmtF(buf []byte, prec int, d decimal) []byte {
        if prec > 0 {
                buf = append(buf, '.')
                for i := 0; i < prec; i++ {
-                       ch := byte('0')
-                       if j := d.exp + i; 0 <= j && j < len(d.mant) {
-                               ch = d.mant[j]
-                       }
-                       buf = append(buf, ch)
+                       buf = append(buf, d.at(d.exp+i))
                }
        }