1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- // Package fastrand implements fast pesudorandom number generator
- // that should scale well on multi-CPU systems.
- //
- // Use crypto/rand instead of this package for generating
- // cryptographically secure random numbers.
- package fastrand
- import (
- "sync"
- "time"
- )
- // Uint32 returns pseudorandom uint32.
- //
- // It is safe calling this function from concurrent goroutines.
- func Uint32() uint32 {
- v := rngPool.Get()
- if v == nil {
- v = &RNG{}
- }
- r := v.(*RNG)
- x := r.Uint32()
- rngPool.Put(r)
- return x
- }
- var rngPool sync.Pool
- // Uint32n returns pseudorandom uint32 in the range [0..maxN).
- //
- // It is safe calling this function from concurrent goroutines.
- func Uint32n(maxN uint32) uint32 {
- x := Uint32()
- // See http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
- return uint32((uint64(x) * uint64(maxN)) >> 32)
- }
- // RNG is a pseudorandom number generator.
- //
- // It is unsafe to call RNG methods from concurrent goroutines.
- type RNG struct {
- x uint32
- }
- // Uint32 returns pseudorandom uint32.
- //
- // It is unsafe to call this method from concurrent goroutines.
- func (r *RNG) Uint32() uint32 {
- for r.x == 0 {
- r.x = getRandomUint32()
- }
- // See https://en.wikipedia.org/wiki/Xorshift
- x := r.x
- x ^= x << 13
- x ^= x >> 17
- x ^= x << 5
- r.x = x
- return x
- }
- // Uint32n returns pseudorandom uint32 in the range [0..maxN).
- //
- // It is unsafe to call this method from concurrent goroutines.
- func (r *RNG) Uint32n(maxN uint32) uint32 {
- x := r.Uint32()
- // See http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
- return uint32((uint64(x) * uint64(maxN)) >> 32)
- }
- func getRandomUint32() uint32 {
- x := time.Now().UnixNano()
- return uint32((x >> 32) ^ x)
- }
|