Pet*_*ter 5 java math performance
我有一个Java程序,可以对Math.tanh()函数进行多次调用.出于好奇,我想与C++进行比较.因此,我编写了两个小程序,一个用Java编写,一个用C++编写,用于测试.
Java代码:
public class TestTanh {
public static void main(String[] args) {
double t1 = -1.0;
double t2 = 1.0;
double step = 1e-8;
double z = 0.0;
for(double t=t1; t<=t2; t += step) {
double y = Math.tanh(t);
z += y;
}
System.out.println("Sum = " + z);
}
}
Run Code Online (Sandbox Code Playgroud)
和C++代码:
#include <iostream>
#include <cmath>
using namespace std;
int main() {
double t1 = -1.0;
double t2 = 1.0;
double step = 1e-8;
double z = 0.0;
for(double t=t1; t<=t2; t += step) {
double y = tanh(t);
z += y;
}
cout << "Sum = " << z << "\n";
}
Run Code Online (Sandbox Code Playgroud)
编译和运行程序我得到以下内容:
$ time java TestTanh
Sum = -0.41281032759865655
real 0m18.372s
user 0m17.961s
sys 0m0.109s
Run Code Online (Sandbox Code Playgroud)
和
$ time ./test_tanh
Sum = -0.41281
real 0m4.022s
user 0m3.641s
sys 0m0.004s
Run Code Online (Sandbox Code Playgroud)
为什么Java程序需要大约5倍的执行时间?它可能与JIT首先进行一些编译有关吗?或者Java中的tanh实现比C++慢?
这是一个简单的测试,可能有一个简单的解释,但我搜索网络,但没有找到答案.我的Java版本是
$ java -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)
Run Code Online (Sandbox Code Playgroud)
在包含其他基本算术运算的较大程序中使用tanh函数时,Java和C++之间的差异变小(现在约为2.3).该程序仍然反复调用tanh,但现在循环中还有其他操作.我也尝试过Apache Commons的FastMath课程,但实际上速度较慢(需要任何特殊设置吗?).该程序具有相同参数的结果是:
C++
real 0m18.031s
user 0m18.007s
sys 0m0.007s
Run Code Online (Sandbox Code Playgroud)
Java与lang.Math
real 0m40.739s
user 0m40.032s
sys 0m0.088s
Run Code Online (Sandbox Code Playgroud)
Java与org.apache.commons.math.util.FastMath
real 0m46.717s
user 0m46.583s
sys 0m0.372s
Run Code Online (Sandbox Code Playgroud)
我的目标是不做任何真正的基准测试,我只想看看在实际情况下以直接的方式实现代码时的差异.
main 方法仅被调用一次,因此 JVM 可能不会将其编译为本机代码。首先阅读如何用 Java 编写正确的微基准测试?
如果微基准写好后仍然存在很大差异,那么可能的原因是JNI开销。该Math.tanh()方法和其他方法已在 JVM 中作为本机代码实现。java.lang.StrictMath的文档说他们使用fdlibm库,它是用 C 编写的,因此您最好在测试中使用该库,这样您就不会比较两个不同的 C 库。