]> Cypherpunks repositories - gostls13.git/commitdiff
math/rand: speed up Float32, Float64
authorRuss Cox <rsc@golang.org>
Tue, 4 Mar 2014 01:43:23 +0000 (20:43 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 4 Mar 2014 01:43:23 +0000 (20:43 -0500)
Actually, speed up Int31n and Int63n by avoiding retry loop.

benchmark           old ns/op    new ns/op    delta
BenchmarkFloat32           32           26  -19.45%
BenchmarkFloat64           46           23  -49.47%

Fixes #7267.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/69980047

src/pkg/math/rand/rand.go
src/pkg/math/rand/rand_test.go

index d3ea84017812613645c55689fca44db699d160b6..0c91f88184eee2fdddb8657eec7bd5e11b596e97 100644 (file)
@@ -60,6 +60,9 @@ func (r *Rand) Int63n(n int64) int64 {
        if n <= 0 {
                panic("invalid argument to Int63n")
        }
+       if n&(n-1) == 0 { // n is power of two, can mask
+               return r.Int63() & (n - 1)
+       }
        max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
        v := r.Int63()
        for v > max {
@@ -74,6 +77,9 @@ func (r *Rand) Int31n(n int32) int32 {
        if n <= 0 {
                panic("invalid argument to Int31n")
        }
+       if n&(n-1) == 0 { // n is power of two, can mask
+               return r.Int31() & (n - 1)
+       }
        max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
        v := r.Int31()
        for v > max {
index c174c613f40c56cb6012f04b16dae82da3198a55..ab0dc49b41128a46b8976b77bc4be1c10ec97dc7 100644 (file)
@@ -376,6 +376,13 @@ func BenchmarkFloat32(b *testing.B) {
        }
 }
 
+func BenchmarkFloat64(b *testing.B) {
+       r := New(NewSource(1))
+       for n := b.N; n > 0; n-- {
+               r.Float64()
+       }
+}
+
 func BenchmarkPerm3(b *testing.B) {
        r := New(NewSource(1))
        for n := b.N; n > 0; n-- {