2017-07-11 11 views
1

ランダムboolを生成する最も速い方法は何ですか?ランダムboolを生成する

は、現在、私はこのようにやっている:

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) 
    } 
} 

どのように私はこれを改善することができますか?

+0

[関数をランダムに返すようにするにはどうすればいいですか?](https://stackoverflow.com/questions/44719156/how-can-i-let-a-function-randomly -return-a-true-or-a-false-in-go/44719269#44719269)。 – icza

+0

なぜsrcとrはグローバル変数ですか?グローバル変数を使用しないようにしてください。それは習慣になり、あなたはそれを続けます。 – sahaj

答えて

1

(それが必要ではなかったとして、必ずしも最速溶液)ランダムbool値を生成する方法の例は、ここで見つけることができる:

How can I let a function randomly return either a true or a false in go

ようなアルゴリズムの最も遅い部分であります常にランダムなデータ(ランダム情報)を取得します。たとえば、rand.Int31()コールでは31個のランダムビットが返されますが、これを使用して1ビットの情報であるboolの値をランダムに生成すると、30ビットが無駄になります(boolの値がランダムに追加される可能性があります)。

rand.Sourceを使用すると、ランダムデータでrand.Randが行う「コードカンフー」のすべてを必要としないので、良い選択です。ランダムな情報源が必要です。

rand.Sourceは、ランダムな情報を取得するための1つの方法を定義:

Int63() int64 

この​​方法は、63個のランダムビットを返します。速い(est)にするには、すべてを使うべきです。もちろん、単一のboolの値を生成するには、そのビットのうちの1つのみが必要ですが、残ったものを保存して、それ以降のランダムboolが要求されたときに使用する必要があります。

これはそれを行うことができる方法である。このようboolgenを作成

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 
} 

は、このようなものです:

func New() *boolgen { 
    return &boolgen{src: rand.NewSource(time.Now().UnixNano())} 
} 

使用例:

r := New() 
for i := 0; i < 100; i++ { 
    if i%10 == 0 { 
     fmt.Println() 
    } 
    fmt.Print(r.Bool(), " ") 
} 

出力例は、(それを試します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 

いくつかの注意:

rand.NewSource()によって返さSourceは、複数のゴルーチンによる同時使用のために安全ではないので、私たちのboolgenも同時使用のために安全ではありません。一方では、この方法で安全なrandパッケージのデフォルトのソースを使用するよりも速くなる(同期が行われないので)が良いです(これは安全ではないので、到達可能になります) "間接的にrandパッケージの機能を通じて)。

あなたは、複数のゴルーチンからこれを使用する必要がある場合は、(質問の精神のように)最速は、すべてのゴルーチンがboolgen自分自身を作成するためになるので、何の同期は必要ありません。

boolgen自体を安全に使用する必要がある場合は、Bool()メソッドをsync.Mutexで保護する必要があります。

関連する問題