github.com/gogf/gf/v2@v2.7.4/util/grand/grand_buffer.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package grand 8 9 import ( 10 "crypto/rand" 11 12 "github.com/gogf/gf/v2/errors/gcode" 13 "github.com/gogf/gf/v2/errors/gerror" 14 ) 15 16 const ( 17 // Buffer size for uint32 random number. 18 bufferChanSize = 10000 19 ) 20 21 var ( 22 // bufferChan is the buffer for random bytes, 23 // every item storing 4 bytes. 24 bufferChan = make(chan []byte, bufferChanSize) 25 ) 26 27 func init() { 28 go asyncProducingRandomBufferBytesLoop() 29 } 30 31 // asyncProducingRandomBufferBytes is a named goroutine, which uses an asynchronous goroutine 32 // to produce the random bytes, and a buffer chan to store the random bytes. 33 // So it has high performance to generate random numbers. 34 func asyncProducingRandomBufferBytesLoop() { 35 var step int 36 for { 37 buffer := make([]byte, 1024) 38 if n, err := rand.Read(buffer); err != nil { 39 panic(gerror.WrapCode(gcode.CodeInternalError, err, `error reading random buffer from system`)) 40 } else { 41 // The random buffer from system is very expensive, 42 // so fully reuse the random buffer by changing 43 // the step with a different number can 44 // improve the performance a lot. 45 // for _, step = range []int{4, 5, 6, 7} { 46 for _, step = range []int{4} { 47 for i := 0; i <= n-4; i += step { 48 bufferChan <- buffer[i : i+4] 49 } 50 } 51 } 52 } 53 }