【发布时间】:2016-12-05 03:54:36
【问题描述】:
我正在测量我的代码的执行时间,并在第一次调用一个方法(从主方法)时发现了一些奇怪的行为。这是我的代码,请看一下
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in)) {
int iNum = input.nextInt();
long lStartTime = System.nanoTime();
// ***********(First call in main) Calling isPrime *************
lStartTime = System.nanoTime();
printResult(isPrime(iNum));
System.out.println("Time Consumed in first call-: "
+ (System.nanoTime() - lStartTime));
// ***********(Second call in main) Calling isPrime *************
lStartTime = System.nanoTime();
printResult(isPrime(iNum));
System.out.println("Time Consumed in second call-: "
+ (System.nanoTime() - lStartTime));
}
}
private static boolean isPrime(int iNum) {
boolean bResult = true;
if (iNum <= 1 || iNum != 2 && iNum % 2 == 0) {
bResult = false;
} else {
double iSqrt = Math.sqrt((double) iNum);
for (int i = 3; i < iSqrt; i += 2) {
if (iNum % i == 0) {
bResult = false;
break;
}
}
}
return bResult;
}
private static void printResult(boolean bResult) {
if (bResult)
System.out.println("\nIt's prime number.");
else
System.out.println("\nIt's not prime number.");
}
输入
5
输出
It's prime number.
Time Consumed in first call-: 484073
It's prime number.
Time Consumed in second call-: 40710
说明
上面我只描述了一个输入和输出的测试用例。但是,第一个方法调用和第二个方法调用之间的执行时间总是存在差异的。
我也以类似的方式尝试了两个以上的方法调用,发现除了一个之外,其他调用之间并没有那么大的差异。除了第一个方法调用 484073ns 之外,其余调用的执行时间在 40710ns 左右(这个执行时间在您的系统上可能不同)。很容易我可以看到在第一个方法调用中存在 484073 - 40710 = 443363ns (大约)的时间开销,但为什么会这样呢?根本原因是什么?
【问题讨论】:
-
第一次调用通常需要编译字节码(一次性成本)。之后,主动 JIT 使后续调用更快(随着时间的推移)。
-
@ElliottFrisch 这种字节码编译(一次性成本)是否仅用于首次调用任何方法(在多个不同方法中)?假设有两个方法
isPrime和isPrime2,这两个方法在main中的调用顺序是isPrime,isPrime2,isPrime,isPrime2。那么第一次调用isPrime2是否会发生字节码的编译(一次性成本)? -
从Just-in-time compilation 上的维基百科条目中,由于加载和编译字节码所花费的时间,JIT 会导致应用程序的初始执行出现轻微延迟到明显延迟。 i> 和甚至更直接 应用程序代码最初被解释,但 JVM 监视哪些字节码序列经常被执行,并将它们转换为机器代码以便在硬件上直接执行。
-
@ElliottFrisch 谢谢,我明白字节码的编译将在第一次调用时发生。请发表您的评论作为答案,以便我可以接受它作为答案。
标签: java performance main execution-time