mirror of
https://github.com/golang/go
synced 2024-11-23 19:50:06 -07:00
math/rand: minor optimization to Perm
Instead of writing out 0..n and then reading it back, just use i when it is needed. Wikipedia calls this the "inside-out" implementation: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle This yields identical values to the previous implementation, given the same seed. (Note that the output from Example_rand is unchanged.) 2.8 GHz Intel Core i7, results very stable: benchmark old ns/op new ns/op delta BenchmarkPerm3 138 136 -1.45% BenchmarkPerm30 825 803 -2.67% Stock Raspberry Pi, minimum improvement out of three runs: benchmark old ns/op new ns/op delta BenchmarkPerm3 5774 5664 -1.91% BenchmarkPerm30 32582 29381 -9.82% R=golang-dev, dave, mtj, adg CC=golang-dev https://golang.org/cl/21030043
This commit is contained in:
parent
1561230ca0
commit
4a18e0edd9
@ -103,12 +103,10 @@ func (r *Rand) Float32() float32 { return float32(r.Float64()) }
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
|
||||
func (r *Rand) Perm(n int) []int {
|
||||
m := make([]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
m[i] = i
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
j := r.Intn(i + 1)
|
||||
m[i], m[j] = m[j], m[i]
|
||||
m[i] = m[j]
|
||||
m[j] = i
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
@ -357,3 +357,17 @@ func BenchmarkInt31n1000(b *testing.B) {
|
||||
r.Int31n(1000)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPerm3(b *testing.B) {
|
||||
r := New(NewSource(1))
|
||||
for n := b.N; n > 0; n-- {
|
||||
r.Perm(3)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPerm30(b *testing.B) {
|
||||
r := New(NewSource(1))
|
||||
for n := b.N; n > 0; n-- {
|
||||
r.Perm(30)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user