我正在测量代码的执行时间,并在第一次调用方法时发现了一些奇怪的行为(来自main方法)。这是我的代码,请看看这个
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 (大约)的时间开销,但为什么会发生?根本原因是什么?
答案 0 :(得分:1)
Java Runtime Environment有多种实现方式,因此并非每个实现都可能像Oracle(以及之前的Sun)一样。
开头说,在大多数当前实现中,方法的初始调用涉及验证和Java字节码的首次编译。因此,该方法的后续调用更快。但是,Java也使用JIT。维基百科在Just-in-time compilation上提供了一个注释
的条目由于加载和编译字节码所花费的时间,JIT会导致应用程序初始执行时出现明显延迟。
接着说,
最初解释应用程序代码,但JVM监视频繁执行哪些字节码序列,并将它们转换为机器代码,以便在硬件上直接执行。