Commit 5a2da562 authored by JT Olio's avatar JT Olio Committed by Robert Griesemer

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 <gri@golang.org>
Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent 7f5434c4
...@@ -462,16 +462,15 @@ func mulDenom(z, x, y nat) nat { ...@@ -462,16 +462,15 @@ func mulDenom(z, x, y nat) nat {
return z.mul(x, y) return z.mul(x, y)
} }
// scaleDenom computes x*f. // scaleDenom sets z to the product x*f.
// If f == 0 (zero value of denominator), the result is (a copy of) x. // If f == 0 (zero value of denominator), z is set to (a copy of) x.
func scaleDenom(x *Int, f nat) *Int { func (z *Int) scaleDenom(x *Int, f nat) {
var z Int
if len(f) == 0 { if len(f) == 0 {
return z.Set(x) z.Set(x)
return
} }
z.abs = z.abs.mul(x.abs, f) z.abs = z.abs.mul(x.abs, f)
z.neg = x.neg z.neg = x.neg
return &z
} }
// Cmp compares x and y and returns: // Cmp compares x and y and returns:
...@@ -481,23 +480,28 @@ func scaleDenom(x *Int, f nat) *Int { ...@@ -481,23 +480,28 @@ func scaleDenom(x *Int, f nat) *Int {
// +1 if x > y // +1 if x > y
// //
func (x *Rat) Cmp(y *Rat) int { 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. // Add sets z to the sum x+y and returns z.
func (z *Rat) Add(x, y *Rat) *Rat { func (z *Rat) Add(x, y *Rat) *Rat {
a1 := scaleDenom(&x.a, y.b.abs) var a1, a2 Int
a2 := scaleDenom(&y.a, x.b.abs) a1.scaleDenom(&x.a, y.b.abs)
z.a.Add(a1, a2) 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) z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
return z.norm() return z.norm()
} }
// Sub sets z to the difference x-y and returns z. // Sub sets z to the difference x-y and returns z.
func (z *Rat) Sub(x, y *Rat) *Rat { func (z *Rat) Sub(x, y *Rat) *Rat {
a1 := scaleDenom(&x.a, y.b.abs) var a1, a2 Int
a2 := scaleDenom(&y.a, x.b.abs) a1.scaleDenom(&x.a, y.b.abs)
z.a.Sub(a1, a2) 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) z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
return z.norm() return z.norm()
} }
...@@ -522,8 +526,9 @@ func (z *Rat) Quo(x, y *Rat) *Rat { ...@@ -522,8 +526,9 @@ func (z *Rat) Quo(x, y *Rat) *Rat {
if len(y.a.abs) == 0 { if len(y.a.abs) == 0 {
panic("division by zero") panic("division by zero")
} }
a := scaleDenom(&x.a, y.b.abs) var a, b Int
b := scaleDenom(&y.a, x.b.abs) a.scaleDenom(&x.a, y.b.abs)
b.scaleDenom(&y.a, x.b.abs)
z.a.abs = a.abs z.a.abs = a.abs
z.b.abs = b.abs z.b.abs = b.abs
z.a.neg = a.neg != b.neg z.a.neg = a.neg != b.neg
......
...@@ -671,3 +671,10 @@ func TestRatSetUint64(t *testing.T) { ...@@ -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)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment