From 5a2da5624a9403a61cdd8df529e2b71129ef7898 Mon Sep 17 00:00:00 2001 From: JT Olio Date: Mon, 6 May 2019 17:38:23 -0600 Subject: [PATCH] math/big: stack allocate scaleDenom return value 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 Reviewed-by: Robert Griesemer --- src/math/big/rat.go | 35 ++++++++++++++++++++--------------- src/math/big/rat_test.go | 7 +++++++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/math/big/rat.go b/src/math/big/rat.go index 675889f33b..c8bf698b18 100644 --- a/src/math/big/rat.go +++ b/src/math/big/rat.go @@ -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 diff --git a/src/math/big/rat_test.go b/src/math/big/rat_test.go index b169477e23..83c5d5cfea 100644 --- a/src/math/big/rat_test.go +++ b/src/math/big/rat_test.go @@ -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) + } +} -- 2.48.1