如果我在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)
每次ln
调用需要115纳秒。
但是在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
相较于Java,Rust的日志速度慢了大约3.7倍(115/31)。
当我测试勾股定理的实现(hypot
)时,Rust的实现比Java快15.8倍。
我写的基准测试有问题还是存在性能问题?
针对评论中提出的问题的回答:
在我的国家,“,”是小数分隔符。
我使用
cargo bench
运行Rust基准测试,它始终在发布模式下运行。Java基准测试框架(JMH)为每个调用创建一个新对象,即使它是静态类和final变量。如果我在测试的方法中添加一个随机创建,那么我得到43 ns/op。
log
应该与 C 中的一致(Java 就不清楚了)。 - Simon ByrneRUSTFLAGS='-Ctarget-cpu=native' cargo bench
é‡چو–°è؟گè،Œوµ‹è¯•م€‚ - kennytmbench_rnd
函数是否会抵消这一点呢?因为该函数仅测试 RNG。这就是为什么 OP 要减去两个 Rust 基准测试时间的原因——以使ln
函数的基准测试更加纯粹。我同意它应该只调用系统数学库。 - Shepmaster