Java 为什么分离方法比相同的内联代码工作得更快

Java 为什么分离方法比相同的内联代码工作得更快,java,methods,coding-style,inline-code,Java,Methods,Coding Style,Inline Code,例如,在大数组中搜索max。使用loop in separate方法的代码比main中相同的内联代码工作得更快。此处运行10次以获得消耗的平均时间: Max generated: 999999 Max is 999999 Time consumed main: 1.8210982999999998 ms Max is 999999 Time consumed method: 0.6809502000000001 ms 最大生成量:999999 最大消耗时间为9999999干管:1.82

例如,在大数组中搜索max。使用loop in separate方法的代码比main中相同的内联代码工作得更快。此处运行10次以获得消耗的平均时间:

Max generated: 999999 Max is 999999 Time consumed main: 1.8210982999999998 ms Max is 999999 Time consumed method: 0.6809502000000001 ms 最大生成量:999999 最大消耗时间为9999999干管:1.8210982999998毫秒 最大消耗时间为999999方法:0.68095020000001毫秒 有人能解释一下为什么会有这样的差异吗?谢谢

import java.util.Random;

public class Main {
    private static int[] data = new int[1000000];
    private final static int COUNT = 10;


    public static void main(String[] args) {
        initData(data);
        long consumedTime;
        long startTime = System.nanoTime();
        int max = 0;
        for (int x = 0; x < COUNT; x++) {
            max  = data[0];
            for (int i = 0; i < data.length; i++) {
                if (data[i] > max) {
                    max = data[i];
                }
            }
        }
        consumedTime =(System.nanoTime() - startTime);
        System.out.println("Max is "+max+ "  Time consumed main: " + (double) (consumedTime)/1000000/COUNT + " ms");


        startTime = System.nanoTime();
        for (int x = 0; x < COUNT; x++) {
            max = getMaxOnPart();
        }
        consumedTime=(System.nanoTime() - startTime);
        System.out.println("Max is "+max+" Time consumed method: " + (double) (consumedTime)/1000000/COUNT + " ms");
    }

    private static void initData(int[] data) {
        final Random random = new Random();
        int max = 0;
        for (int i = 0; i < data.length; i++) {
            data[i] = random.nextInt(1000000);
            if (max < data[i]) {
                max = data[i];
            }
        }
        System.out.println("  Max generated: " + max);
    }

    private static int getMaxOnPart() {
        int max = data[0];
        for (int i = 0; i < data.length; i++) {
            if (data[i] > max) {
                max = data[i];
            }
        }
        return max;
    }
}
import java.util.Random;
公共班机{
私有静态整数[]数据=新整数[1000000];
私有最终静态整数计数=10;
公共静态void main(字符串[]args){
初始数据(数据);
消耗时间长;
long startTime=System.nanoTime();
int max=0;
对于(int x=0;x最大值){
max=数据[i];
}
}
}
consumedTime=(System.nanoTime()-startTime);
System.out.println(“最大值为”+Max+“主消耗时间:”+(双精度)(消耗时间)/1000000/计数+“毫秒”);
startTime=System.nanoTime();
对于(int x=0;x最大值){
max=数据[i];
}
}
返回最大值;
}
}

测量不正确/不一致。在第一个循环中

long startTime = System.nanoTime();
在10个重复循环之外,因此

consumedTime+=(System.nanoTime() - startTime);
测量
1x+2x+3x+…
,这会将结果高估55倍(如果我的数学正确的话)

而第二个调用的函数测量会重置重复x 10循环内的
startTime

 startTime = System.nanoTime();
 max = getMaxOnPart();
 consumedTime+=(System.nanoTime() - startTime);

这将仅仅是该方法所用时间的总和。

您的代码中似乎有一些错误,但这些只是直接的问题。我将概述为什么在这里不测量任何非常有用的东西的大图

只有对代码的执行进行非常详细和细致的分析,才能准确地回答特定性能概要背后的实际原因。为什么?因为它依赖于影响JVM即时编译器复杂功能的潜在大量因素

然而,这一点是肯定的:你不会被答案所启发,因为它与你的代码没有太大关系;相反,它将与您选择如何测试它有关

只是想了解一下您可能期望的答案:大多数优化的粒度级别是方法,并且只有在证明某个方法是热点(默认情况下,它必须累积10000次调用)之后,才会对其进行JIT编译。因此,当您将代码提取到一个方法中时,您将在执行编译后立即获得编译的好处


然而,也有堆栈替换技术,即在执行方法时对方法进行优化。这就是内联案例中必须依赖的内容。优化器将检测方法中间的热循环并编译。但是,这是一种非常不同的机制,因此您可以预期不同的结果。

实际上,我解决了他的问题,并且该方法仍然快了很多。我将发布一个答案,以便您可以看到新代码。由于第一个循环的开始时间测量错误,更改了原始帖子。第二个看起来很好。它增加了10倍的时间消耗,就像第一次一样。