为什么第一个方法调用总是耗时最长?
Why does the first method call always take the longest?
在 Stack Overflow 上阅读了类似的主题后,我编写了以下代码来了解 System.nanoTime()
的一致性。
它只是在一个空的void函数的方法调用前后调用System.nanoTime()
,记录过程中经过的时间。然而,正如您在结果中看到的那样,第一个调用总是耗时最长。这是什么原因?
public class Test {
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
double start = System.nanoTime();
foo();
double end = System.nanoTime();
double diff = end - start;
System.out.println("Diff: " + diff);
}
}
public static void foo() {
}
}
结果:
Diff: 2765.0
Diff: 509.0
Diff: 236.0
Diff: 238.0
Diff: 230.0
Diff: 539.0
Diff: 359.0
Diff: 356.0
Diff: 380.0
Diff: 353.0
请注意,我确实阅读了这个问题:Why does first call to java.io.File.createTempFile(String,String,File) take 5 seconds on Citrix?
此外,这个link对以后的参考很有帮助,但不一定能回答我的具体问题:How do I write a correct micro-benchmark in Java?
JVM 延迟执行 Class 解析(参见 JVMS 5.4.3)。在您的情况下,常量池中对 foo
的符号引用在第一次执行 invokestatic
字节码时解析,即在第一次调用该方法时解析。显然,这比仅仅执行一个已经解析的字节码需要更多的时间。
在 Stack Overflow 上阅读了类似的主题后,我编写了以下代码来了解 System.nanoTime()
的一致性。
它只是在一个空的void函数的方法调用前后调用System.nanoTime()
,记录过程中经过的时间。然而,正如您在结果中看到的那样,第一个调用总是耗时最长。这是什么原因?
public class Test {
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
double start = System.nanoTime();
foo();
double end = System.nanoTime();
double diff = end - start;
System.out.println("Diff: " + diff);
}
}
public static void foo() {
}
}
结果:
Diff: 2765.0
Diff: 509.0
Diff: 236.0
Diff: 238.0
Diff: 230.0
Diff: 539.0
Diff: 359.0
Diff: 356.0
Diff: 380.0
Diff: 353.0
请注意,我确实阅读了这个问题:Why does first call to java.io.File.createTempFile(String,String,File) take 5 seconds on Citrix?
此外,这个link对以后的参考很有帮助,但不一定能回答我的具体问题:How do I write a correct micro-benchmark in Java?
JVM 延迟执行 Class 解析(参见 JVMS 5.4.3)。在您的情况下,常量池中对 foo
的符号引用在第一次执行 invokestatic
字节码时解析,即在第一次调用该方法时解析。显然,这比仅仅执行一个已经解析的字节码需要更多的时间。