为什么内联Math.max会使代码速度超过200倍?

Kam*_*osz 8 java performance

我最近开始对一些Java代码进行基准测试,以便为我的程序获得最佳性能结果,并注意到一些奇怪的事情.也就是说,我已经对以下方法进行了基准测试:

private static final int n = 10000;

public static void test0(){
    int m = 0;

    for(int i = 0; i < n; ++i){
        m = Math.max(i, m);
    }
}

public static void test1(){
    int m = 0;

    for(int i = 0; i < n; ++i){
        m = ((i >= m) ? i : m);
    }
}
Run Code Online (Sandbox Code Playgroud)

得到了那些结果:

          | Test 0          | Test 1          | 
----------+-----------------+-----------------+-
Average:  | 51,77 ns        | 13956,63 ns     | 
Best:     | 0,00 ns         | 6514,00 ns      | 
Worst:    | 25,45 ms        | 60,50 ms        | 
Tries:    | 16971233        | 16971233        | 
Run Code Online (Sandbox Code Playgroud)

在搜索SO之后(即Math.max(a,b)或(a> b)?a:b在Java中更快?)对我来说确实test1不应该这么慢.

这些方法在30秒内在8个线程上随机测试,我运行的每个基准测试似乎都相似.我用jdk1.8.0_45.

那么,为什么test1比它慢200多倍test0呢?

Jea*_*art 4

由于Math.max是静态函数,编译器可能会发现代码根本不执行任何操作,而是通过不执行它来优化执行!

变量m是函数的本地变量,分配它没有帮助,因为它永远不会被读取。

您需要确保执行以某种方式修改某些内容,以便编译器不会对其进行积极优化。

例如,您可以简单地m在测试结束时打印 的值,或者创建m一个可以稍后访问的类变量,甚至可以按照我最初在评论中建议的方式对结果求和。