Але*_*ков 16 java floating-point microbenchmark rust jmh
如果我在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());
}
Run Code Online (Sandbox Code Playgroud)
结果是:
test tests::bench_ln ... bench: 121 ns/iter (+/- 2)
test tests::bench_rnd ... bench: 6 ns/iter (+/- 0)
Run Code Online (Sandbox Code Playgroud)
每次ln通话121-6 = 115 ns .
但是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);
}
Run Code Online (Sandbox Code Playgroud)
给我:
Benchmark Mode Cnt Score Error Units
Main.testLog avgt 20 31,555 ± 0,234 ns/op
Run Code Online (Sandbox Code Playgroud)
日志在Rust中比在Java中慢约3.7倍(115/31).
当我测试斜边实现(hypot)时,Rust中的实现比Java快15.8倍.
我写过不好的基准测试,还是性能问题?
回答评论中提出的问题:
","是我国的小数点分隔符.
我运行Rust的基准测试cargo bench,总是在发布模式下运行.
Java基准框架(JMH)为每个调用创建一个新对象,即使它是一个static类和一个final变量.如果我在测试方法中添加随机创建,我得到43 ns/op.
答案由@kennytm给出:
export RUSTFLAGS='-Ctarget-cpu=native'
Run Code Online (Sandbox Code Playgroud)
解决了这个问题.之后,结果是:
test tests::bench_ln ... bench: 43 ns/iter (+/- 3)
test tests::bench_rnd ... bench: 5 ns/iter (+/- 0)
Run Code Online (Sandbox Code Playgroud)
我认为38(±3)足够接近31.555(±0.234).
因为我不知道Rust,所以我将提供另外一半的解释.Math.log注释的@HotSpotIntrinsicCandidate含义是它将被本机CPU指令替换为这样的操作:想想Integer.bitCount要做很多移位或者使用直接CPU指令来做得更快.
有一个非常简单的程序,如下所示:
public static void main(String[] args) {
System.out.println(mathLn(20_000));
}
private static long mathLn(int x) {
long result = 0L;
for (int i = 0; i < x; ++i) {
result = result + ln(i);
}
return result;
}
private static final long ln(int x) {
return (long) Math.log(x);
}
Run Code Online (Sandbox Code Playgroud)
运行它:
java -XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining
-XX:+PrintIntrinsics
-XX:CICompilerCount=2
-XX:+PrintCompilation
package/Classname
Run Code Online (Sandbox Code Playgroud)
它会生成很多行,但其中一行是:
@ 2 java.lang.Math::log (5 bytes) intrinsic
Run Code Online (Sandbox Code Playgroud)
使这段代码非常快.
我真的不知道什么时候以及如何在Rust中发生......
| 归档时间: |
|
| 查看次数: |
1335 次 |
| 最近记录: |