ThreadRng arbeitet fünfmal langsamer als ThreadLocalRandom in Java.
Ich führe diesen Benchmark in Rust aus:
#[bench]
fn bench_rnd(b: &mut Bencher) {
b.iter(|| rand::thread_rng().gen_range::<f64>(2.0, 100.0));
}
Auf meinem Laptop ist das Ergebnis:
test tests::bench_rnd ... Bench: 49 ns/iter (+/- 1)
Aber wenn ich den gleichen Benchmark auf JHM ausführe:
<strong i="12">@Benchmark</strong>
public double testRnd() {
return ThreadLocalRandom.current().nextDouble(2, 100);
}
Auf meinem Laptop ist das Ergebnis:
Benchmark-Modus Cnt Score Fehlereinheiten
Main.testRnd avgt 20 9.018 ± 0,094 ns/op
Der Unterschied ist also 5,44 mal, sieht nach einem Leistungsfehler aus.
Rost:
rbose
rustc 1.20.0-nächtlich (c9bb93576 2017-06-24)
binär: rost
Commit-Hash: c9bb93576d4484edd1b3c40eb2aea0dfa0788851
Zusagedatum: 2017-06-24
host: x86_64-unknown-linux-gnu
Release: 1.20.0-nächtlich
LLVM-Version: 4.0
Java:
OpenJDK 1.8.131
Da rand
eine externe Kiste mit eigenem Repository ist, gehört dieses Problem wahrscheinlich dorthin , es sei denn, Sie können irgendwie nachweisen, dass dies die Schuld von Rust ist und nicht die Schuld von rand
.
Die Frage, die Sie sich jedoch wirklich stellen sollten, lautet: Welche Art von Zufallszahlen erhalten Sie? rand::ThreadRng
ist ein kryptographisch sicherer RNG, daher wird er einen inhärenten Leistungsnachteil gegenüber RNGs haben, die nicht so sicher sein müssen. Wenn Sie sich die Dokumentation ansehen ... "Instanzen von ThreadLocalRandom sind nicht kryptographisch sicher." Das bedeutet, dass Sie nicht einmal einen fairen Vergleich anstellen.
Das Ausführen Ihres Benchmarks wie geschrieben ist für mich 21 ns / iter.
Das Ändern Ihres Benchmarks, um das Ergebnis von thread_rng()
beschleunigt es für mich um 15 ns/Iter.
#[bench]
fn bench_rnd(b: &mut Bencher) {
let mut rng = rand::thread_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}
Wenn ich jedoch weak_rng()
und die kryptografische Sicherheit wegwerfe, rast es auf 3 ns/iter vor.
#[bench]
fn bench_rnd(b: &mut Bencher) {
let mut rng = rand::weak_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}
Beachten Sie auch, dass ThreadLocalRandom
Java ein extrem einfaches lineares kongruentes PRNG ist , während rand
thread_rng()
Rust auf dem kryptographisch sicheren PRNG von ISAAC (angeblich) basiert, das teurer ist, daher ist dieser Benchmark kein exakter Apfel-zu-Apfel-Vergleich.
Vielen Dank für die Erklärung.
Hilfreichster Kommentar
Da
rand
eine externe Kiste mit eigenem Repository ist, gehört dieses Problem wahrscheinlich dorthin , es sei denn, Sie können irgendwie nachweisen, dass dies die Schuld von Rust ist und nicht die Schuld vonrand
.Die Frage, die Sie sich jedoch wirklich stellen sollten, lautet: Welche Art von Zufallszahlen erhalten Sie?
rand::ThreadRng
ist ein kryptographisch sicherer RNG, daher wird er einen inhärenten Leistungsnachteil gegenüber RNGs haben, die nicht so sicher sein müssen. Wenn Sie sich die Dokumentation ansehen ... "Instanzen von ThreadLocalRandom sind nicht kryptographisch sicher." Das bedeutet, dass Sie nicht einmal einen fairen Vergleich anstellen.Das Ausführen Ihres Benchmarks wie geschrieben ist für mich 21 ns / iter.
Das Ändern Ihres Benchmarks, um das Ergebnis von
thread_rng()
beschleunigt es für mich um 15 ns/Iter.Wenn ich jedoch
weak_rng()
und die kryptografische Sicherheit wegwerfe, rast es auf 3 ns/iter vor.