github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/internal/fastrand/fastrand_test.go (about) 1 // Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package fastrand 6 7 import ( 8 "fmt" 9 "sync" 10 "testing" 11 "time" 12 13 "golang.org/x/exp/rand" 14 ) 15 16 type defaultRand struct { 17 mu sync.Mutex 18 src rand.PCGSource 19 } 20 21 func newDefaultRand() *defaultRand { 22 r := &defaultRand{} 23 r.src.Seed(uint64(time.Now().UnixNano())) 24 return r 25 } 26 27 func (r *defaultRand) Uint32() uint32 { 28 r.mu.Lock() 29 i := uint32(r.src.Uint64()) 30 r.mu.Unlock() 31 return i 32 } 33 34 func BenchmarkFastRand(b *testing.B) { 35 b.RunParallel(func(pb *testing.PB) { 36 for pb.Next() { 37 Uint32() 38 } 39 }) 40 } 41 42 func BenchmarkDefaultRand(b *testing.B) { 43 r := newDefaultRand() 44 b.RunParallel(func(pb *testing.PB) { 45 for pb.Next() { 46 r.Uint32() 47 } 48 }) 49 } 50 51 // Benchmarks for single-threaded (ST) use of fastrand compared to 52 // constructing a Rand, which can have heap allocation overhead. 53 54 // Global state to disable elision of benchmark code. 55 var xg uint32 56 57 func BenchmarkSTFastRand(b *testing.B) { 58 var x uint32 59 for i := 0; i < b.N; i++ { 60 // Arbitrary constant. 61 x = Uint32n(2097152) 62 } 63 xg = x 64 } 65 66 func BenchmarkSTDefaultRand(b *testing.B) { 67 for _, newPeriod := range []int{0, 10, 100, 1000} { 68 name := "no-new" 69 if newPeriod > 0 { 70 name = fmt.Sprintf("new-period=%d", newPeriod) 71 } 72 b.Run(name, func(b *testing.B) { 73 r := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 74 b.ResetTimer() 75 var x uint32 76 for i := 0; i < b.N; i++ { 77 if newPeriod > 0 && i%newPeriod == 0 { 78 r = rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 79 } 80 // Arbitrary constant. 81 x = uint32(r.Uint64n(2097152)) 82 } 83 xg = x 84 }) 85 } 86 }