Gdybym uruchomić te standardy w Rust:Dlaczego logarytm jest wolniejszy w Rust niż w Javie?
#[bench]
fn bench_rnd(b: &mut Bencher) {
let mut rng = rand::weak_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}
#[bench]
fn bench_ln(b: &mut Bencher) {
let mut rng = rand::weak_rng();
b.iter(|| rng.gen_range::<f64>(2.0, 100.0).ln());
}
Wynikiem jest:
test tests::bench_ln ... bench: 121 ns/iter (+/- 2)
test tests::bench_rnd ... bench: 6 ns/iter (+/- 0)
121-6 = 115 ns na ln
rozmowy.
Ale ten sam punkt odniesienia w Javie:
@State(Scope.Benchmark)
public static class Rnd {
final double x = ThreadLocalRandom.current().nextDouble(2, 100);
}
@Benchmark
public double testLog(Rnd rnd) {
return Math.log(rnd.x);
}
Daje mi:
Benchmark Mode Cnt Score Error Units
Main.testLog avgt 20 31,555 ± 0,234 ns/op
Rejestr jest ~ 3,7 razy wolniej (115/31) w Rust niż w Javie.
Kiedy testuję wykonanie przeciwprostokątnej (hypot
), implementacja w Rust jest 15,8 razy szybsza niż w Javie.
Czy napisałem złe testy porównawcze lub jest to problem z wydajnością?
Odpowiedzi na pytania zadane w komentarzach:
"" jest separator dziesiętny w moim kraju.
Prowadzę benchmark Rusta przy użyciu
cargo bench
, który zawsze działa w trybie zwolnienia.Środowisko testowe Java (JMH) tworzy nowy obiekt dla każdego połączenia, mimo że jest to klasa
static
ifinal
zmienna. Jeśli dodaję losową kreację do testowanej metody, otrzymam 43 ns/op.
Czy nie można używać java jako punktu odniesienia? Chodzi mi o to, że Java jest fajna, ale w niektórych przypadkach jest zbyt fajna. – Wietlol
Prawdopodobnie porównujesz generator liczb losowych bardziej niż funkcję rejestru. Wierzę również, że Rust po prostu używa systemowej biblioteki matematycznej, więc czyste wywołanie 'log' powinno być takie samo jak w C (nie ma pojęcia o Javie). –
Czy możesz ponownie uruchomić test, używając 'RUSTFLAGS = '- Ctarget-cpu = rodzimej" ławki ładunkowej "? – kennytm