Java 为什么分离方法比相同的内联代码工作得更快
例如,在大数组中搜索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毫秒 有人能解释一下为什么会有这样的差异吗?谢谢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
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倍的时间消耗,就像第一次一样。