github.com/gogf/gf@v1.16.9/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  
    13  const (
    14  	// Buffer size for uint32 random number.
    15  	bufferChanSize = 10000
    16  )
    17  
    18  var (
    19  	// bufferChan is the buffer for random bytes,
    20  	// every item storing 4 bytes.
    21  	bufferChan = make(chan []byte, bufferChanSize)
    22  )
    23  
    24  func init() {
    25  	go asyncProducingRandomBufferBytesLoop()
    26  }
    27  
    28  // asyncProducingRandomBufferBytes is a named goroutine, which uses a asynchronous goroutine
    29  // to produce the random bytes, and a buffer chan to store the random bytes.
    30  // So it has high performance to generate random numbers.
    31  func asyncProducingRandomBufferBytesLoop() {
    32  	var step int
    33  	for {
    34  		buffer := make([]byte, 1024)
    35  		if n, err := rand.Read(buffer); err != nil {
    36  			panic(err)
    37  		} else {
    38  			// The random buffer from system is very expensive,
    39  			// so fully reuse the random buffer by changing
    40  			// the step with a different number can
    41  			// improve the performance a lot.
    42  			// for _, step = range []int{4, 5, 6, 7} {
    43  			for _, step = range []int{4} {
    44  				for i := 0; i <= n-4; i += step {
    45  					bufferChan <- buffer[i : i+4]
    46  				}
    47  			}
    48  		}
    49  	}
    50  }