Rust: Bug de performances ThreadRng

Créé le 8 juil. 2017  ·  3Commentaires  ·  Source: rust-lang/rust

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.

Méta

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

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

Tous les 3 commentaires

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.

Cette page vous a été utile?
0 / 5 - 0 notes