Skip to content

Commit

Permalink
shuffle: improve performance by 80%
Browse files Browse the repository at this point in the history
This improves the performance of BenchmarkNew by 80%. Wrapping the rand
reader in a bufio reader had the biggest impact on performance.
  • Loading branch information
davidlazar committed Feb 10, 2018
1 parent 39c7ee2 commit f7a2cbb
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
18 changes: 10 additions & 8 deletions shuffle/shuffle.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package shuffle // import "vuvuzela.io/crypto/shuffle"

import (
"bufio"
"encoding/binary"
"io"
)
Expand All @@ -14,8 +15,10 @@ type Shuffler []int

func New(rand io.Reader, n int) Shuffler {
p := make(Shuffler, n)
buf := make([]byte, 4)
rr := bufio.NewReader(rand)
for i := range p {
p[i] = intn(rand, i+1)
p[i] = intn(rr, uint32(i+1), buf)
}
return p
}
Expand All @@ -34,17 +37,16 @@ func (s Shuffler) Unshuffle(x [][]byte) {
}
}

func intn(rand io.Reader, n int) int {
func intn(rand *bufio.Reader, n uint32, buf []byte) int {
max := ^uint32(0)
m := max % uint32(n)
r := make([]byte, 4)
m := max - (max % n)
for {
if _, err := rand.Read(r); err != nil {
if _, err := rand.Read(buf); err != nil {
panic(err)
}
x := binary.BigEndian.Uint32(r)
if x < max-m {
return int(x % uint32(n))
x := binary.BigEndian.Uint32(buf)
if x < m {
return int(x % n)
}
}
}
6 changes: 6 additions & 0 deletions shuffle/shuffle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ func TestShuffle(t *testing.T) {
}
}
}

func BenchmarkNew(b *testing.B) {
for i := 0; i < b.N; i++ {
New(rand.Reader, 50000)
}
}

0 comments on commit f7a2cbb

Please sign in to comment.