例如在大数组中搜索max。带有循环的单独方法的代码比main中的相同内联代码工作得更快。这里运行10次以消耗平均时间:
Max generated: 999999 Max is 999999 Time consumed main: 1.8210982999999998 ms Max is 999999 Time consumed method: 0.6809502000000001 ms
有人可以解释为何有这样的差异?感谢。
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;
}
}
答案 0 :(得分:1)
您无法正确/一致地进行测量。在第一个循环中
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);
这将只计算方法中所用的时间。
答案 1 :(得分:1)
您的代码中似乎有一些错误,但这些只是当前的问题。我将概述为什么你不会在这里测量任何非常有用的东西。
只有通过对代码执行的非常详细和细致的分析,才能获得关于某个性能配置文件背后的实际原因的准确答案。为什么?因为它依赖于可能影响JVM即时编译器复杂功能的大量因素。
然而,这是肯定的:你不会被答案所启发,因为它与你的代码没有多大关系;相反,它将与确切地选择如何测试相关。
只是为了感受一下您可能期望的答案:大多数优化的粒度级别是方法,并且只有在经过验证后才能对方法进行JIT编译。是一个热点(默认情况下,它将累积10,000次调用)。因此,当您将代码提取到某个方法时,只要执行该编译,您就会收到编译的好处。
但是,还有堆栈替换技术,其中方法在执行时进行了优化。这是您在内联案例中必须依赖的内容。优化器将检测方法中间的热循环并进行编译。然而,这是一种非常不同的机制,因此您可以期待不同的结果。