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
// 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
}
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)
+ }
+}