2017-07-11 3 views
1

Was ist der schnellste Weg, um eine zufällige Bool in gehen zu generieren?generieren Sie eine zufällige Bool in gehen

derzeit wie folgt ich tue:

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

Wie kann ich das verbessern?

+0

Mögliches Duplikat von [Wie kann ich eine Funktion zufallsbedingt entweder ein wahres oder ein falsches loslassen lassen] (https://stackoverflow.com/questions/44719156/how-can-i-let-a-function-random) -return-entweder-ein-wahr-oder-ein-falsch-in-go/44719269 # 44719269). – icza

+0

Warum src und r sind globale Variablen? Versuchen Sie, globale Variablen nicht zu verwenden. Es wird zur Gewohnheit und dann geht es weiter. – sahaj

Antwort

1

Beispiele, wie ein zufälligen bool Wert erzeugen finden Sie hier (nicht unbedingt die schnellsten Lösungen, wie, dass es keine Voraussetzung war):

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

solcher Algorithmen Der langsamste Teil ist immer die Zufallsdaten (zufällige Informationen) bekommen. Zum Beispiel gibt ein Aufruf 31 zufällige Bits zurück, aber wenn wir es nur verwenden, um einen zufälligen bool Wert zu erzeugen (was 1 Bit Information ist), verschwenden wir 30 Bits (was 30 zusätzliche zufällige bool Werte sein könnten!).

Verwenden rand.Source ist eine gute Wahl, da wir nicht alle "Code Kung-Fu" benötigen, die rand.Rand auf die zufälligen Daten macht. Wir brauchen nur eine Quelle von zufälligen Informationen.

rand.Source definiert ein Verfahren Zufallsinformation zu erhalten:

Int63() int64 

Diese Methode liefert Source.Int63() 63 Zufallsbits; um schnell zu sein (est), sollten wir alle benutzen. Um einen einzelnen bool Wert zu erzeugen, benötigt man natürlich nur 1 seiner Bits, aber wir sollten die restlichen speichern und sie verwenden, wenn nachfolgende zufällige bool s von uns gefragt werden.

Dies ist, wie es getan werden kann:

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

Erstellen eines boolgen ist wie folgt:

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

Beispiel Nutzung:

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

Beispiel Ausgabe (versuchen Sie es auf die 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 

Einige Anmerkungen:

Die Source zurück von rand.NewSource() ist für die gleichzeitige Nutzung durch mehrere goroutines nicht sicher, so dass unsere boolgen auch nicht sicher für die gleichzeitige Verwendung ist. Auf der einen Seite ist dies gut, da es schneller sein wird (da keine Synchronisation stattfindet) als die Verwendung der Standard-Quelle des rand Pakets, die auf diese Weise sicher ist (die übrigens nicht exportiert wird, so kann nur "erreicht werden "indirekt über Funktionen des rand Pakets."

Wenn Sie dies aus mehreren goroutines verwenden, schnellste (wie im Geist der Frage) wäre für alle goroutines ihre eigenen boolgen zu schaffen, so ist keine Synchronisation erforderlich.

Wenn boolgen selbst für die gleichzeitige Verwendung gesichert werden muss, sollte einfach die Bool() Methode mit einem sync.Mutex geschützt werden.

Verwandte Themen