Merge branch 'fast-rand'
This commit is contained in:
commit
ed7837591a
|
@ -4,11 +4,17 @@ import (
|
|||
crip "crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"nullprogram.com/x/rng"
|
||||
)
|
||||
|
||||
var (
|
||||
sharedRand *rand.Rand
|
||||
getSharedRand = &sync.Once{}
|
||||
)
|
||||
|
||||
// RandomStrChoice returns a random item from an input slice of strings.
|
||||
func RandomStrChoice(choice []string) string {
|
||||
if len(choice) > 0 {
|
||||
|
@ -25,7 +31,8 @@ func GetCryptoSeed() int64 {
|
|||
return seed
|
||||
}
|
||||
|
||||
// GetOptimizedRand returns a pointer to a new rand.Rand which uses crypto/rand to seed a splitmix64 rng.
|
||||
// GetOptimizedRand returns a pointer to a *new* rand.Rand which uses crypto/rand to seed a splitmix64 rng.
|
||||
// Does not use the global/shared instance of a splitmix64 rng, but instead creates a new one.
|
||||
func GetOptimizedRand() *rand.Rand {
|
||||
r := new(rng.SplitMix64)
|
||||
r.Seed(GetCryptoSeed())
|
||||
|
@ -34,14 +41,25 @@ func GetOptimizedRand() *rand.Rand {
|
|||
|
||||
// RNGUint32 returns a random uint32 using crypto/rand and splitmix64.
|
||||
func RNGUint32() uint32 {
|
||||
r := GetOptimizedRand()
|
||||
return r.Uint32()
|
||||
getSharedRand.Do(func() {
|
||||
sharedRand = GetOptimizedRand()
|
||||
})
|
||||
return sharedRand.Uint32()
|
||||
}
|
||||
|
||||
// RNG returns integer with a maximum amount of 'n' using crypto/rand and splitmix64.
|
||||
/*RNG returns integer with a maximum amount of 'n' using a global/shared instance of a splitmix64 rng.
|
||||
- Benchmark_FastRandStr5-24 25205089 47.03 ns/op
|
||||
- Benchmark_FastRandStr25-24 7113620 169.8 ns/op
|
||||
- Benchmark_FastRandStr55-24 3520297 340.7 ns/op
|
||||
- Benchmark_FastRandStr500-24 414966 2837 ns/op
|
||||
- Benchmark_FastRandStr55555-24 3717 315229 ns/op
|
||||
|
||||
*/
|
||||
func RNG(n int) int {
|
||||
r := GetOptimizedRand()
|
||||
return r.Intn(n)
|
||||
getSharedRand.Do(func() {
|
||||
sharedRand = GetOptimizedRand()
|
||||
})
|
||||
return sharedRand.Intn(n)
|
||||
}
|
||||
|
||||
// OneInA generates a random number with a maximum of 'million' (input int).
|
||||
|
|
|
@ -2,6 +2,7 @@ package entropy
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -41,10 +42,10 @@ func Test_RandStr(t *testing.T) {
|
|||
for n := 0; n != 500; n++ {
|
||||
zero := RandStr(55)
|
||||
one := RandStr(55)
|
||||
t.Logf("Random0: %s Random1: %s", zero, one)
|
||||
// t.Logf("Random0: %s Random1: %s", zero, one)
|
||||
randStrChecks(zero, one, t)
|
||||
}
|
||||
|
||||
t.Logf("[SUCCESS] RandStr had no collisions")
|
||||
}
|
||||
|
||||
func Test_RandStr_Entropy(t *testing.T) {
|
||||
|
@ -67,10 +68,10 @@ func Test_RandStr_Entropy(t *testing.T) {
|
|||
t.Errorf("[ENTROPY FAILURE] more than a quarter of the string is the same!\n zero: %s \n one: %s \nTotal similar: %d",
|
||||
zero, one, similarity)
|
||||
}
|
||||
t.Logf("[ENTROPY] Similarity score (lower is better): %d", similarity)
|
||||
// t.Logf("[ENTROPY] Similarity score (lower is better): %d", similarity)
|
||||
totalScore += similarity
|
||||
}
|
||||
t.Logf("[ENTROPY] final score (lower is better): %d", totalScore)
|
||||
t.Logf("[ENTROPY] final score (lower is better): %d (RandStr)", totalScore)
|
||||
}
|
||||
|
||||
func Test_RandomStrChoice(t *testing.T) {
|
||||
|
@ -83,3 +84,40 @@ func Test_RandomStrChoice(t *testing.T) {
|
|||
}
|
||||
check(RandomStrChoice(slice), RandomStrChoice(slice), t)
|
||||
}
|
||||
|
||||
func Test_RNGUint32(t *testing.T) {
|
||||
// start globals fresh, just for coverage.
|
||||
sharedRand = GetOptimizedRand()
|
||||
getSharedRand = &sync.Once{}
|
||||
RNGUint32()
|
||||
}
|
||||
|
||||
func Benchmark_RandStr5(b *testing.B) {
|
||||
for n := 0; n != b.N; n++ {
|
||||
RandStr(5)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_RandStr25(b *testing.B) {
|
||||
for n := 0; n != b.N; n++ {
|
||||
RandStr(25)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_RandStr55(b *testing.B) {
|
||||
for n := 0; n != b.N; n++ {
|
||||
RandStr(55)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_RandStr500(b *testing.B) {
|
||||
for n := 0; n != b.N; n++ {
|
||||
RandStr(500)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_RandStr55555(b *testing.B) {
|
||||
for n := 0; n != b.N; n++ {
|
||||
RandStr(55555)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue