Если я запустил эти тесты в Rust:
#[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());
}
Результат:
test tests::bench_ln ... bench: 121 ns/iter (+/- 2)
test tests::bench_rnd ... bench: 6 ns/iter (+/- 0)
121-6 = 115 нс на вызов ln
.
Но тот же тест в Java:
@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);
}
Дает мне:
Benchmark Mode Cnt Score Error Units
Main.testLog avgt 20 31,555 ± 0,234 ns/op
В Rust log более ~ 3.7 раз медленнее (115/31), чем в Java.
Когда я тестирую реализацию гипотенузы (hypot
), реализация в Rust в 15,8 раза быстрее, чем в Java.
Я написал плохие тесты или это проблема производительности?
Ответы на вопросы, заданные в комментариях:
-
"," является десятичным разделителем в моей стране.
-
Я запускаю тест Rust с помощью
cargo bench
, который всегда запускается в режиме выпуска. -
Базовая среда Java (JMH) создает новый объект для каждого вызова, хотя это класс
static
и переменнаяfinal
. Если я добавлю случайное создание в тестируемый метод, я получаю 43 нс/оп.