summaryrefslogtreecommitdiff
path: root/test/bench/pidigits.go
diff options
context:
space:
mode:
authorEvan Shaw <chickencha@gmail.com>2010-04-20 20:39:36 -0700
committerEvan Shaw <chickencha@gmail.com>2010-04-20 20:39:36 -0700
commit46914854ff711a1dd6f46ab7c62f78acade05a72 (patch)
tree97187583895cbbfba584e51112fbea6541318de9 /test/bench/pidigits.go
parentc6746a7efa9025613f143569c338ebc5ffba7913 (diff)
downloadgolang-46914854ff711a1dd6f46ab7c62f78acade05a72.tar.gz
big: Add Lsh and Value; convert pidigits to use big
This yields a pretty significant performance boost to pidigits and there are still some improvements to be made. Here are my numbers: amd64 w/ bignum: pidigits 10000 gcc -O2 pidigits.c -lgmp 2.10u 0.00s 2.10r gc pidigits 22.92u 0.02s 22.97r gc_B pidigits 22.62u 0.00s 22.65r amd64 w/ big: pidigits 10000 gcc -O2 pidigits.c -lgmp 2.09u 0.02s 2.11r gc pidigits 12.68u 0.04s 12.72r gc_B pidigits 12.71u 0.03s 12.75r 386 w/ bignum: pidigits 10000 gcc -O2 pidigits.c -lgmp 2.09u 0.00s 2.09r gc pidigits 44.30u 0.01s 44.35r gc_B pidigits 44.29u 0.03s 44.35r 386 w/ big: pidigits 10000 gcc -O2 pidigits.c -lgmp 2.10u 0.00s 2.10r gc pidigits 22.70u 0.06s 22.79r gc_B pidigits 22.80u 0.09s 22.91r R=rsc, gri CC=golang-dev http://codereview.appspot.com/881050 Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'test/bench/pidigits.go')
-rw-r--r--test/bench/pidigits.go50
1 files changed, 28 insertions, 22 deletions
diff --git a/test/bench/pidigits.go b/test/bench/pidigits.go
index aaa9f53a5..a05515028 100644
--- a/test/bench/pidigits.go
+++ b/test/bench/pidigits.go
@@ -38,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
package main
import (
- "bignum"
+ "big"
"flag"
"fmt"
)
@@ -47,11 +47,14 @@ var n = flag.Int("n", 27, "number of digits")
var silent = flag.Bool("s", false, "don't print result")
var (
- tmp1 *bignum.Integer
- tmp2 *bignum.Integer
- numer = bignum.Int(1)
- accum = bignum.Int(0)
- denom = bignum.Int(1)
+ tmp1 = big.NewInt(0)
+ tmp2 = big.NewInt(0)
+ y2 = big.NewInt(0)
+ bigk = big.NewInt(0)
+ numer = big.NewInt(1)
+ accum = big.NewInt(0)
+ denom = big.NewInt(1)
+ ten = big.NewInt(10)
)
func extract_digit() int64 {
@@ -60,36 +63,39 @@ func extract_digit() int64 {
}
// Compute (numer * 3 + accum) / denom
- tmp1 = numer.Shl(1)
- bignum.Iadd(tmp1, tmp1, numer)
- bignum.Iadd(tmp1, tmp1, accum)
- tmp1, tmp2 := tmp1.QuoRem(denom)
+ tmp1.Lsh(numer, 1)
+ tmp1.Add(tmp1, numer)
+ tmp1.Add(tmp1, accum)
+ tmp1.DivMod(tmp1, denom, tmp2)
// Now, if (numer * 4 + accum) % denom...
- bignum.Iadd(tmp2, tmp2, numer)
+ tmp2.Add(tmp2, numer)
// ... is normalized, then the two divisions have the same result.
if tmp2.Cmp(denom) >= 0 {
return -1
}
- return tmp1.Value()
+ return tmp1.Int64()
}
func next_term(k int64) {
- y2 := k*2 + 1
-
- tmp1 = numer.Shl(1)
- bignum.Iadd(accum, accum, tmp1)
- bignum.Iscale(accum, y2)
- bignum.Iscale(numer, k)
- bignum.Iscale(denom, y2)
+ // TODO(eds) If big.Int ever gets a Scale method, y2 and bigk could be int64
+ y2.New(k*2 + 1)
+ bigk.New(k)
+
+ tmp1.Lsh(numer, 1)
+ accum.Add(accum, tmp1)
+ accum.Mul(accum, y2)
+ numer.Mul(numer, bigk)
+ denom.Mul(denom, y2)
}
func eliminate_digit(d int64) {
- bignum.Isub(accum, accum, denom.Mul1(d))
- bignum.Iscale(accum, 10)
- bignum.Iscale(numer, 10)
+ tmp := big.NewInt(0).Set(denom)
+ accum.Sub(accum, tmp.Mul(tmp, big.NewInt(d)))
+ accum.Mul(accum, ten)
+ numer.Mul(numer, ten)
}
func printf(s string, arg ...interface{}) {