Rust: Error de rendimiento de ThreadRng

Creado en 8 jul. 2017  ·  3Comentarios  ·  Fuente: rust-lang/rust

ThreadRng funciona 5 veces más lento que ThreadLocalRandom en Java.

Ejecuto este punto de referencia en Rust:

#[bench]
fn bench_rnd(b: &mut Bencher) {
    b.iter(|| rand::thread_rng().gen_range::<f64>(2.0, 100.0));
}

En mi computadora portátil, el resultado es:
pruebas de prueba :: bench_rnd ... bench: 49 ns / iter (+/- 1)

Pero si ejecuto el mismo punto de referencia en JHM:

<strong i="12">@Benchmark</strong>
public double testRnd() {
    return ThreadLocalRandom.current().nextDouble(2, 100);
}

En mi computadora portátil, el resultado es:
Unidades de error de puntuación de Cnt del modo de referencia
Main.testRnd avgt 20 9.018 ± 0.094 ns / op

Entonces, la diferencia es 5.44 veces parece un error de rendimiento.

Meta

Oxido:

rbose
rustc 1.20.0-todas las noches (c9bb93576 2017-06-24)
binario: rustc
commit-hash: c9bb93576d4484edd1b3c40eb2aea0dfa0788851
fecha de compromiso: 2017-06-24
host: x86_64-unknown-linux-gnu
lanzamiento: 1.20.0-nightly
Versión LLVM: 4.0

Java:
OpenJDK 1.8.131

Comentario más útil

Dado que rand es una caja externa con su propio repositorio, este problema probablemente pertenece allí , a menos que pueda demostrar de alguna manera que esto es culpa de Rust y no de rand .

Sin embargo, la pregunta que realmente debería hacerse es ¿qué tipo de números aleatorios está obteniendo? rand::ThreadRng es un RNG criptográficamente seguro, por lo que tendrá una desventaja de rendimiento inherente a los RNG que no tienen que ser tan seguros. Mirando la documentación ... "Las instancias de ThreadLocalRandom no son criptográficamente seguras", lo que significa que ni siquiera estás haciendo una comparación justa.

Ejecutar su punto de referencia como está escrito es 21ns / iter para mí.

Modificar su punto de referencia para almacenar en caché el resultado de thread_rng() acelera 15 ns / iter para mí.

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

Sin embargo, si uso weak_rng() y descarto la seguridad criptográfica, avanza a 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));
}

Todos 3 comentarios

Dado que rand es una caja externa con su propio repositorio, este problema probablemente pertenece allí , a menos que pueda demostrar de alguna manera que esto es culpa de Rust y no de rand .

Sin embargo, la pregunta que realmente debería hacerse es ¿qué tipo de números aleatorios está obteniendo? rand::ThreadRng es un RNG criptográficamente seguro, por lo que tendrá una desventaja de rendimiento inherente a los RNG que no tienen que ser tan seguros. Mirando la documentación ... "Las instancias de ThreadLocalRandom no son criptográficamente seguras", lo que significa que ni siquiera estás haciendo una comparación justa.

Ejecutar su punto de referencia como está escrito es 21ns / iter para mí.

Modificar su punto de referencia para almacenar en caché el resultado de thread_rng() acelera 15 ns / iter para mí.

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

Sin embargo, si uso weak_rng() y descarto la seguridad criptográfica, avanza a 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));
}

También tenga en cuenta que ThreadLocalRandom Java es un PRNG congruencial lineal extremadamente simple, mientras que rand Rust thread_rng() se basa en el PRNG criptográficamente seguro de ISAAC (presuntamente) que es más caro, por lo que este punto de referencia no es exactamente una comparación de manzana a manzana.

Muchas gracias por la explicacion

¿Fue útil esta página
0 / 5 - 0 calificaciones