Java数学运算符的相对性能
大家好,有人提到过Java数学运算符的相对性能/成本吗 理想情况下类似于代码完成2(我现在手头上没有) 它可能看起来像这样:Java数学运算符的相对性能,java,performance,optimization,benchmarking,Java,Performance,Optimization,Benchmarking,大家好,有人提到过Java数学运算符的相对性能/成本吗 理想情况下类似于代码完成2(我现在手头上没有) 它可能看起来像这样: 增补:1 减法:2 乘法:10 分区:100 对数:600 指数:500 谢谢 我迅速编写了这个快速、非正式、完全不科学的测试代码: import java.util.function.BinaryOperator; public class Test { private static void test(String desc, BinaryOperato
- 增补:1
- 减法:2
- 乘法:10
- 分区:100
- 对数:600
- 指数:500
谢谢 我迅速编写了这个快速、非正式、完全不科学的测试代码:
import java.util.function.BinaryOperator;
public class Test {
private static void test(String desc, BinaryOperator<Double> op, double a, double b, long startIter)
{
long maxIter = startIter;
long elapsed;
do {
maxIter *= 2;
long start = System.currentTimeMillis();
for (long niter = 0; niter < maxIter; ++niter) {
double res = op.apply(a, b);
}
elapsed = System.currentTimeMillis() - start;
} while (elapsed <= 10_000);
System.out.printf("%-15s/sec\t%g\n",
desc, (maxIter * 1000.0) / elapsed);
}
public static void main(String[] arg)
{
test("Addition (double)", (Double a, Double b) -> {
return a + b;
}, 483902.7743, 42347.775, 10_000_000);
test("Subtraction (double)", (Double a, Double b) -> {
return a - b;
}, 483902.7743, 42347.775, 10_000_000);
test("Multiplication (double)", (Double a, Double b) -> {
return a * b;
}, 483902.7743, 42347.775, 1_000_000);
test("Division (double)", (Double a, Double b) -> {
return a / b;
}, 483902.7743, 42347.775, 1_000_000);
test("Log10", (Double a, Double b) -> {
return Math.log10(a);
}, 483902.7743, 42347.775, 1_000_000);
test("LogE", (Double a, Double b) -> {
return Math.log(a);
}, 483902.7743, 42347.775, 1_000_000);
test("Power", (Double a, Double b) -> {
return Math.pow(a, b);
}, 483902.7743, 12, 100_000);
}
}
转换为相对性能,我们有:
Addition 1.0
Subtraction 1.5
Multiplication 18.9
Division 19.2
Log10 31.0
LogE 31.1
Power 71.3
和往常一样,您的里程可能会有所不同 你能更明确地回答你的问题吗?这些数字意味着什么?这是否意味着“除法比加法慢100倍”?如果你问我的话,听起来很有趣。这在很大程度上取决于您的确切代码的外观、JVM进行了多少次优化、生成的机器代码的外观以及您的确切处理器如何执行。创建有意义的基准肯定不容易。例如,请注意,许多处理器使用查找表来执行某些频繁的乘法和其他任务(它们的结果只是预先计算并存储在表中),因此它们可以立即返回答案。这个字段充满了优化,你很难在基准测试中进行控制;对于(inti=0;i<100;i++){sum++;},JVM会将其转换为单个语句
intsum=100字节码(.class文件)中的code>。这样看来,添加速度会非常快。在那里很容易遇到这种错误的假设。@Zabuza JVM无法在.class文件中转换类似的东西。编译器可以,但它不能。JVM可以在运行时对其进行优化,但不能在.class文件.Hmmm中进行优化,感谢@Zabuza的输入。然而,从我的理解来看,它不是正统地教导我们,作为一个一般的规则,除法总是比加法更昂贵,例如(在任何数值计算课上)?例如,看看这里的渐进复杂性:虽然我确信性能可能有一些微妙之处,但我认为总的来说,可以为JavaThank指定一些一般规则,这或多或少就是我想要的!不过,我一直想知道的一件事是,在每次迭代中使用Random来获取数字是否更好,因为我担心(可能是不合理的)编译器优化使用相同的数字(缓存),或者可能只是因为这个数字很容易记在日志中,例如由于查找表(回想起Zabuza所说的)是的,使用各种不同的论点可能会给出一个更现实的画面。我不期望总体排名有任何戏剧性的变化,只是更好地估计相对性能。例如,你可能会发现乘法“真的”19或14个加法,而不是18个,但它永远不会是3或4个加法,日志可能“真的”是28或34个加法,但可能永远不会少于一个乘法…-1尝试“乘法、减法、加法”的顺序来了解原因。谷歌为bi和megamorphic调用站点了解。使用JMH来做正确的事情。
Addition 1.0
Subtraction 1.5
Multiplication 18.9
Division 19.2
Log10 31.0
LogE 31.1
Power 71.3