ThreadRng fonctionne 5 fois plus lentement que ThreadLocalRandom en Java.
Je lance ce benchmark dans Rust :
#[bench]
fn bench_rnd(b: &mut Bencher) {
b.iter(|| rand::thread_rng().gen_range::<f64>(2.0, 100.0));
}
Sur mon portable, le résultat est :
test tests::bench_rnd ... banc: 49 ns/iter (+/- 1)
Mais si je lance le même benchmark sur JHM :
<strong i="12">@Benchmark</strong>
public double testRnd() {
return ThreadLocalRandom.current().nextDouble(2, 100);
}
Sur mon portable, le résultat est :
Unités d'erreur de score Cnt du mode de référence
Main.testRnd moy 20 9 018 ± 0,094 ns/op
Donc, la différence est de 5,44 fois ressemble à un bug de performance.
Rouiller:
rbose
rustc 1.20.0-nuit (c9bb93576 2017-06-24)
binaire : rouillec
commit-hachage : c9bb93576d4484edd1b3c40eb2aea0dfa0788851
date d'engagement : 2017-06-24
hôte : x86_64-unknown-linux-gnu
version : 1.20.0-nuit
Version LLVM : 4.0
Java:
OpenJDK 1.8.131
Puisque rand
est un crate externe avec son propre référentiel, ce problème y appartient probablement, à moins que vous ne puissiez démontrer d'une manière ou d'une autre que c'est la faute de Rust, et non rand
la faute de
Cependant, la question que vous devriez vraiment vous poser est de savoir quel type de nombres aléatoires obtenez-vous ? rand::ThreadRng
est un RNG cryptographiquement sécurisé, il va donc présenter un désavantage inhérent en termes de performances par rapport aux RNG qui n'ont pas besoin d'être aussi sécurisés. En regardant la documentation... "Les instances de ThreadLocalRandom ne sont pas sécurisées cryptographiquement. " ce qui signifie que vous ne faites même pas une comparaison équitable.
Exécuter votre benchmark tel qu'il est écrit est de 21ns/iter pour moi.
Modifier votre benchmark pour mettre en cache le résultat de thread_rng()
accélère de 15 ns/iter pour moi.
#[bench]
fn bench_rnd(b: &mut Bencher) {
let mut rng = rand::thread_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}
Cependant, si j'utilise weak_rng()
et que je supprime la sécurité cryptographique, cela passe à 3 ns/iter.
#[bench]
fn bench_rnd(b: &mut Bencher) {
let mut rng = rand::weak_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}
Notez également que Java de ThreadLocalRandom
est un extrêmement simple PRNG congruence linéaire , tandis que Rust rand
de thread_rng()
est basé sur l'ISAAC (revendiquée à être) cryptographiquement sécurisé PRNG qui est plus cher, donc cette référence n'est pas exactement une comparaison pomme à pomme.
Merci beaucoup pour l'explication.
Commentaire le plus utile
Puisque
rand
est un crate externe avec son propre référentiel, ce problème y appartient probablement, à moins que vous ne puissiez démontrer d'une manière ou d'une autre que c'est la faute de Rust, et nonrand
la faute deCependant, la question que vous devriez vraiment vous poser est de savoir quel type de nombres aléatoires obtenez-vous ?
rand::ThreadRng
est un RNG cryptographiquement sécurisé, il va donc présenter un désavantage inhérent en termes de performances par rapport aux RNG qui n'ont pas besoin d'être aussi sécurisés. En regardant la documentation... "Les instances de ThreadLocalRandom ne sont pas sécurisées cryptographiquement. " ce qui signifie que vous ne faites même pas une comparaison équitable.Exécuter votre benchmark tel qu'il est écrit est de 21ns/iter pour moi.
Modifier votre benchmark pour mettre en cache le résultat de
thread_rng()
accélère de 15 ns/iter pour moi.Cependant, si j'utilise
weak_rng()
et que je supprime la sécurité cryptographique, cela passe à 3 ns/iter.