]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: stack allocate scaleDenom return value
authorJT Olio <hello@jtolio.com>
Mon, 6 May 2019 23:38:23 +0000 (17:38 -0600)
committerRobert Griesemer <gri@golang.org>
Wed, 8 May 2019 17:11:57 +0000 (17:11 +0000)
benchmark             old ns/op     new ns/op     delta
BenchmarkRatCmp-4     154           77.9          -49.42%

Change-Id: I932710ad8b6905879e232168b1777927f86ba22a
Reviewed-on: https://go-review.googlesource.com/c/go/+/175460
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/math/big/rat.go
src/math/big/rat_test.go

index 675889f33b18f1f254151288b555d56976c3a206..c8bf698b184970a82a934e7566385be759865f3d 100644 (file)
@@ -462,16 +462,15 @@ func mulDenom(z, x, y nat) nat {
        return z.mul(x, y)
 }
 
-// scaleDenom computes x*f.
-// If f == 0 (zero value of denominator), the result is (a copy of) x.
-func scaleDenom(x *Int, f nat) *Int {
-       var z Int
+// scaleDenom sets z to the product x*f.
+// If f == 0 (zero value of denominator), z is set to (a copy of) x.
+func (z *Int) scaleDenom(x *Int, f nat) {
        if len(f) == 0 {
-               return z.Set(x)
+               z.Set(x)
+               return
        }
        z.abs = z.abs.mul(x.abs, f)
        z.neg = x.neg
-       return &z
 }
 
 // Cmp compares x and y and returns:
@@ -481,23 +480,28 @@ func scaleDenom(x *Int, f nat) *Int {
 //   +1 if x >  y
 //
 func (x *Rat) Cmp(y *Rat) int {
-       return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs))
+       var a, b Int
+       a.scaleDenom(&x.a, y.b.abs)
+       b.scaleDenom(&y.a, x.b.abs)
+       return a.Cmp(&b)
 }
 
 // Add sets z to the sum x+y and returns z.
 func (z *Rat) Add(x, y *Rat) *Rat {
-       a1 := scaleDenom(&x.a, y.b.abs)
-       a2 := scaleDenom(&y.a, x.b.abs)
-       z.a.Add(a1, a2)
+       var a1, a2 Int
+       a1.scaleDenom(&x.a, y.b.abs)
+       a2.scaleDenom(&y.a, x.b.abs)
+       z.a.Add(&a1, &a2)
        z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
        return z.norm()
 }
 
 // Sub sets z to the difference x-y and returns z.
 func (z *Rat) Sub(x, y *Rat) *Rat {
-       a1 := scaleDenom(&x.a, y.b.abs)
-       a2 := scaleDenom(&y.a, x.b.abs)
-       z.a.Sub(a1, a2)
+       var a1, a2 Int
+       a1.scaleDenom(&x.a, y.b.abs)
+       a2.scaleDenom(&y.a, x.b.abs)
+       z.a.Sub(&a1, &a2)
        z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
        return z.norm()
 }
@@ -522,8 +526,9 @@ func (z *Rat) Quo(x, y *Rat) *Rat {
        if len(y.a.abs) == 0 {
                panic("division by zero")
        }
-       a := scaleDenom(&x.a, y.b.abs)
-       b := scaleDenom(&y.a, x.b.abs)
+       var a, b Int
+       a.scaleDenom(&x.a, y.b.abs)
+       b.scaleDenom(&y.a, x.b.abs)
        z.a.abs = a.abs
        z.b.abs = b.abs
        z.a.neg = a.neg != b.neg
index b169477e239e012e546d43ce5aab71caba0a02b6..83c5d5cfea163e3655860cb9eeb65d406da56bb3 100644 (file)
@@ -671,3 +671,10 @@ func TestRatSetUint64(t *testing.T) {
                }
        }
 }
+
+func BenchmarkRatCmp(b *testing.B) {
+       x, y := NewRat(4, 1), NewRat(7, 2)
+       for i := 0; i < b.N; i++ {
+               x.Cmp(y)
+       }
+}