ThreadRng funciona 5 vezes mais devagar do que ThreadLocalRandom em Java.
Eu executo este benchmark no Rust:
#[bench]
fn bench_rnd(b: &mut Bencher) {
b.iter(|| rand::thread_rng().gen_range::<f64>(2.0, 100.0));
}
No meu laptop, o resultado é:
testes de teste :: bench_rnd ... bench: 49 ns / iter (+/- 1)
Mas se eu executar o mesmo benchmark no JHM:
<strong i="12">@Benchmark</strong>
public double testRnd() {
return ThreadLocalRandom.current().nextDouble(2, 100);
}
No meu laptop, o resultado é:
Unidades de erro de pontuação do Cnt do modo de benchmark
Main.testRnd avgt 20 9.018 ± 0,094 ns / op
Portanto, a diferença é de 5,44 vezes parece bug de desempenho.
Ferrugem:
rbose
rustc 1.20.0-nightly (c9bb93576 24-06-2017)
binário: rustc
commit-hash: c9bb93576d4484edd1b3c40eb2aea0dfa0788851
data de confirmação: 24-06-2017
host: x86_64-unknown-linux-gnu
lançamento: 1.20.0 noturno
LLVM versão: 4.0
Java:
OpenJDK 1.8.131
Visto que rand
é uma caixa externa com seu próprio repositório, este problema provavelmente pertence lá , a menos que você seja capaz de demonstrar de alguma forma que isso é culpa do Rust, e não de rand
.
No entanto, a pergunta que você realmente deveria fazer é: que tipo de números aleatórios você está recebendo? rand::ThreadRng
é um RNG criptograficamente seguro, portanto, terá uma desvantagem de desempenho inerente aos RNGs que não precisam ser tão seguros. Olhando a documentação ... "Instâncias de ThreadLocalRandom não são criptograficamente seguras." O que significa que você nem mesmo está fazendo uma comparação justa.
Executar seu benchmark conforme escrito é 21 ns / iter para mim.
Modificar seu benchmark para armazenar em cache o resultado de thread_rng()
acelera 15 ns / iter para mim.
#[bench]
fn bench_rnd(b: &mut Bencher) {
let mut rng = rand::thread_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}
Se eu usar weak_rng()
no entanto e descartar a segurança criptográfica, ela avançará para 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));
}
Observe também que de Java ThreadLocalRandom
é extremamente simples PRNG congruência linear , enquanto o Rust rand
's thread_rng()
baseia-se no ISAAC (reivindicou-a-ser) PRNG criptograficamente segura que é mais caro, portanto, este benchmark não é exatamente uma comparação maçã com maçã.
Muito obrigado pela explicação.
Comentários muito úteis
Visto que
rand
é uma caixa externa com seu próprio repositório, este problema provavelmente pertence lá , a menos que você seja capaz de demonstrar de alguma forma que isso é culpa do Rust, e não derand
.No entanto, a pergunta que você realmente deveria fazer é: que tipo de números aleatórios você está recebendo?
rand::ThreadRng
é um RNG criptograficamente seguro, portanto, terá uma desvantagem de desempenho inerente aos RNGs que não precisam ser tão seguros. Olhando a documentação ... "Instâncias de ThreadLocalRandom não são criptograficamente seguras." O que significa que você nem mesmo está fazendo uma comparação justa.Executar seu benchmark conforme escrito é 21 ns / iter para mim.
Modificar seu benchmark para armazenar em cache o resultado de
thread_rng()
acelera 15 ns / iter para mim.Se eu usar
weak_rng()
no entanto e descartar a segurança criptográfica, ela avançará para 3 ns / iter.