java.util.Random.nextDouble () ist langsam für mich und ich brauche etwas sehr schnelles.
Ich habe einige Google-Suche gemacht und ich habe nur Integer-basierte schnelle Zufallsgeneratoren gefunden. Ist hier irgendwas für reelle Zahlen aus Intervall & lt; 0, 1)?
Wenn Sie etwas schnell brauchen und Zugriff auf Java8 haben, kann ich Ihnen java.utils
SplitableRandom . Es ist schneller (~ doppelt so schnell) und hat eine bessere statistische Verteilung.
Wenn Sie einen noch schnelleren oder besseren Algorithmus benötigen, kann ich eine dieser spezialisierten XorShift-Varianten empfehlen:
Informationen zu diesen Algorithmen und ihrer Qualität finden Sie in diesem großen PRNG-Vergleich .
Ich habe einen unabhängigen Leistungsvergleich durchgeführt. Sie können die detaillierten Ergebnisse und den Code hier finden: github.com/tobijdc/PRNG-Performance
TLDR
Benutze niemals java.util.Random
, benutze java.util.SplittableRandom
.
Wenn Sie schneller oder besser PRNG benötigen, verwenden Sie eine XorShift-Variante.
Sie könnten eine auf ganzzahligen Zahlen basierende Zufallszahl so ändern, dass sie im Intervall [0,1] wie folgt verdoppelt:
%Vor%Wenn randInt () jedoch eine 32-Bit-Ganzzahl erzeugt, füllt dies nicht alle Bits des Doppelworts, weil das Doppelte 53 Mantissenbits hat. Sie könnten natürlich zwei zufällige Ganzzahlen erzeugen, um alle Mantissenbits zu füllen. Oder Sie können sich den Quellcode der Ramdom.nextDouble () Implementierung ansehen. Es verwendet fast sicher eine Ganzzahl RNG und wandelt einfach die Ausgabe in eine Doppel.
Was die Leistung angeht, sind die leistungsstärksten Zufallszahlengeneratoren lineare Kongruenzgeneratoren. Von diesen empfehle ich den Generator für numerische Rezepte. Sie können mehr Informationen über LCGs von Wikipedia sehen: Ссылка
Wenn Sie jedoch eine gute Zufälligkeit wünschen und die Leistung nicht so wichtig ist, denke ich Mersenne Twister ist die beste Wahl. Es hat auch eine Wikipedia-Seite: Ссылка
Es gibt einen neuen Zufallszahlengenerator namens PCG, der in Ссылка erklärt wird. Dies ist im Wesentlichen ein Nachbearbeitungsschritt für LCG, der die Zufälligkeit der LCG-Ausgabe verbessert. Beachten Sie, dass PCG langsamer als LCG ist, weil es einfach ein Nachbearbeitungsschritt für LCG ist. Wenn also die Leistung sehr wichtig ist und die Zufälligkeit nicht so wichtig ist, möchten Sie LCG statt PCG verwenden.
Beachten Sie, dass keiner der genannten Generatoren kryptographisch sicher ist. Wenn Sie die Werte für kryptografische Anwendungen verwenden müssen, sollten Sie einen kryptografisch sicheren Algorithmus verwenden. Ich glaube jedoch nicht, dass Dubletten für die Kryptographie verwendet werden würden.
Beachten Sie, dass all diese Lösungen eine fundamentale Tatsache übersehen (die mir vor ein paar Wochen noch nicht bewusst war): Der Übergang von 64 Bit zu einem Doppelten mit einer Multiplikation ist ein großer Zeitverlust. Die Implementierung von xorshift128 + und xorshift1024 + in den DSI-Dienstprogrammen ( Ссылка ) verwendet direkte Bitmanipulation und die Ergebnisse sind beeindruckend.
Siehe die Benchmarks für nextDouble () bei
und die Qualität berichtet bei
Imho sollten Sie juhists Antwort nur akzeptieren - hier ist der Grund.
nextDouble ist langsam, weil es zwei Aufrufe von next () aufruft - es steht genau dort in der Dokumentation.
Ihre besten Optionen sind also:
Hier ist ein überlanger Benchmark mit Java's Random, einer LCG (so schlecht wie java.util.Random) und Marsaglias Universalgenerator (die Version, die Doubles erzeugt).
%Vor% Haben Sie tatsächlich Benchmarking oder Profiling durchgeführt, um zu zeigen, dass nextDouble
der Flaschenhals ist? Haben Sie Alternativen wie MersenneTwister Streams-Bibliothek ? Ich schlage vor, diejenigen mit Benchmarking zu versuchen, aber es gibt kein kostenloses Mittagessen. Verbesserungen bei der Geschwindigkeit werden wahrscheinlich zu Lasten der Qualität gehen und umgekehrt.
Tags und Links java random performance generator double