生成随机布尔的最快方法是什么?
目前我正在这样做:
package main
import (
"fmt"
"math/rand"
"time"
)
// random generator
var src = rand.NewSource(time.Now().UnixNano())
var r = rand.New(src)
func main() {
for i := 0; i < 100; i++ {
// generate a random boolean and print it
fmt.Printf("bool: %s\n", r.Intn(2) != 0)
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何改善呢?
我只是一个菜鸟,但这对我来说比提供的其他解决方案更有意义:
package randbool
import (
"math/rand"
"time"
)
/*
RandBool
This function returns a random boolean value based on the current time
*/
func RandBool() bool {
rand.Seed(time.Now().UnixNano())
return rand.Intn(2) == 1
}
Run Code Online (Sandbox Code Playgroud)
我对 go 不太熟悉,所以请原谅我的格式。
bool可以在此处找到如何生成随机值的示例(不一定是最快的解决方案,因为这不是必需的):
这种算法最慢的部分总是获取随机数据(随机信息)。例如,rand.Int31()调用返回31个随机位,但是如果仅使用它“生成”一个随机bool值(信息的1位),则会浪费30位(可能是30个附加的随机bool值!)。
使用rand.Source是一个不错的选择,因为我们rand.Rand不需要对随机数据执行的所有“代码功夫” 。我们只需要一个随机信息源。
rand.Source 定义了一种获取随机信息的方法:
Int63() int64
Run Code Online (Sandbox Code Playgroud)
该Source.Int63()方法返回63个随机位;为了最快(最好),我们应该全部使用。当然,生成单个bool值仅需要其位中的1个,但是我们应该存储其余的位,并bool在要求我们随后的random时使用它们。
这是可以做到的:
type boolgen struct {
src rand.Source
cache int64
remaining int
}
func (b *boolgen) Bool() bool {
if b.remaining == 0 {
b.cache, b.remaining = b.src.Int63(), 63
}
result := b.cache&0x01 == 1
b.cache >>= 1
b.remaining--
return result
}
Run Code Online (Sandbox Code Playgroud)
创建这样的boolgen是这样的:
func New() *boolgen {
return &boolgen{src: rand.NewSource(time.Now().UnixNano())}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
r := New()
for i := 0; i < 100; i++ {
if i%10 == 0 {
fmt.Println()
}
fmt.Print(r.Bool(), " ")
}
Run Code Online (Sandbox Code Playgroud)
输出示例(在Go Playground上尝试):
false false true true false false false false false false
false false false true false false true false true true
false false true false true false false true true true
false false false false false false false true true false
true true true true false false false false true false
true true true false true true true true true true
true true false true true false false true false true
true true false false false true true true true false
true false false true true true true false false true
true false false false false false false false true false
Run Code Online (Sandbox Code Playgroud)
一些注意事项:
该Source由归国rand.NewSource()是用于多个够程同时使用安全的,所以我们boolgen也是同时使用并不安全。一方面,这是一件好事,因为它将比使用rand包的默认源更快(因为不会发生同步),而这种方式是安全的(通过未导出的方式,因此只能通过“间接”到达)rand包的功能)。
如果您需要在多个goroutine中使用它,那么所有的goroutine都将创建自己的,这是最快的(按照问题的实质)boolgen,因此不需要同步。
如果boolgen必须确保它本身可以安全地并发使用,则只需使用即可Bool()保护其方法sync.Mutex。