为什么Rust中的对数比Java中的对数慢?
如果我在Rust中运行这些基准测试:为什么Rust中的对数比Java中的对数慢?,java,floating-point,rust,microbenchmark,jmh,Java,Floating Point,Rust,Microbenchmark,Jmh,如果我在Rust中运行这些基准测试: #[工作台] fn工作台(b:和多台工作台){ 设mut rng=rand::weak_rng(); b、 国际热核实验堆(| | rng.gen_范围::(2.0100.0)); } #[法官席] fn台架(b:和多台台架){ 设mut rng=rand::weak_rng(); b、 国际热核实验堆(| | rng.gen_范围::(2.0100.0).ln()); } 结果是: 测试测试::测试台\u ln。。。试验台:121纳秒/国际热核实验堆(+
#[工作台]
fn工作台(b:和多台工作台){
设mut rng=rand::weak_rng();
b、 国际热核实验堆(| | rng.gen_范围::(2.0100.0));
}
#[法官席]
fn台架(b:和多台台架){
设mut rng=rand::weak_rng();
b、 国际热核实验堆(| | rng.gen_范围::(2.0100.0).ln());
}
结果是:
测试测试::测试台\u ln。。。试验台:121纳秒/国际热核实验堆(+/-2)
测试:台架试验。。。实验台:6纳秒/国际热核实验堆(+/-0)
121-6=115纳秒/次ln
呼叫
但Java中的基准相同:
@State(Scope.Benchmark)
公共静态类Rnd{
final double x=ThreadLocalRandom.current().nextDouble(2100);
}
@基准
公共双测试日志(Rnd Rnd){
返回Math.log(rnd.x);
}
给我:
基准模式Cnt分数错误单位
Main.testLog avgt 20 31555±0234 ns/op
Rust中的日志速度约为Java中的3.7倍(115/31)
当我测试斜边实现(hypot
)时,Rust中的实现速度是Java中的15.8倍
我是否编写了糟糕的基准测试,或者这是一个性能问题
对评论中提出的问题的答复:
货台
运行Rust的基准测试静态
类和最终
变量。如果我在测试方法中添加一个随机创建,我得到43 ns/op测试测试::测试台\u ln。。。实验台:43纳秒/国际热核实验堆(+/-3)
测试:台架试验。。。实验台:5纳秒/国际热核实验堆(+/-0)
我认为38(±3)足够接近31.555(±0.234)。我将提供另一半的解释,因为我不知道生锈
Math.log
用@hostpotintrinsiccandidate
注释,这意味着对于这样的操作,它将被本机CPU指令所取代:想想Integer.bitCount
,它将执行大量移位,或者使用速度更快的直接CPU指令
有这样一个非常简单的程序:
publicstaticvoidmain(字符串[]args){
系统输出打印Ln(mathLn(20_000));
}
私有静态long-mathLn(int x){
长结果=0L;
对于(int i=0;i
并使用以下工具运行它:
java-XX:+UnlockDiagnosticVMOptions
-XX:+printinline
-XX:+PrintIntrinsics
-XX:CICompilerCount=2
-XX:+打印编译
包/类名
它将生成许多行,但其中之一是:
@2 java.lang.Math::log(5字节)内在
使这段代码非常快
我真的不知道什么时候,如何发生在生锈,虽然 用java作为基准不是很糟糕吗?我的意思是java很好,但在某些情况下,它太好了。你可能在测试随机数生成器,而不是日志函数。此外,我相信Rust只使用系统数学库,因此对
log
的纯调用应该与C中的调用相同(不知道Java)。您是否可以使用RUSTFLAGS='-Ctarget cpu=native'cargo bench
?@SimonByrne重新运行测试,这难道不会被只测试RNG的bench\u rnd
功能所抵消吗?这就是OP减去两个Rust基准计时的原因——为ln
函数创建一个纯粹的基准。我同意它应该只调用系统数学库。我对java一无所知,但你确定x是更新的吗?因为Rust是静态编译的(或者AOT,如果你愿意的话),所以它必须知道一个编译到的平台。默认情况下,它有点保守(例如,32位x86代码可能针对686处理器)。-Ctarget cpu=native
标志告诉编译器以运行编译器的机器为目标;这允许编译器使用完整的可用指令集(如popcnt
示例)。
export RUSTFLAGS='-Ctarget-cpu=native'