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.
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
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
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 derand
.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í.Sin embargo, si uso
weak_rng()
y descarto la seguridad criptográfica, avanza a 3 ns / iter.