所以我的问题更为笼统。我有以下简单的代码:
for(int i=0;i<10;i++){
long starttime=System.nanoTime();
System.out.println("test");
long runtime=System.nanoTime()-starttime;
System.out.println(i + ":" +"runtime="+runtime);
}
我收到以下输出:
test
0:runtime=153956
test
1:runtime=15396
test
2:runtime=22860
test
3:runtime=11197
test
4:runtime=11197
test
5:runtime=12129
test
6:runtime=11663
test
7:runtime=11664
test
8:runtime=53185
test
9:runtime=12130
第一个和第二个运行时之间区别的原因是什么?提前感谢=)
答案 0 :(得分:21)
JVM和标准库中的许多内容都被懒惰地初始化以改善JVM启动时间。所以你第一次执行这行
System.out.println("test");
重量级初始化过程发生。完成它的时间包含在您的第一次测量中。后续调用沿着已经初始化状态的快速路径继续进行。
您可以在Java中对大量API调用观察到相同的效果。
当然,还有很多因素可以影响完成任何给定方法调用所需的时间,特别是如果它在其路径上包含系统调用。但是,第一次调用的延迟中的异常值是特殊的,因为它具有潜在的确定性原因,因此可靠地重现。
答案 1 :(得分:17)
很多事情都会影响你的计算。
您计算机上的其他进程怎么样?您是否认为 JVM正在升温?也许垃圾收集?所有这些因素和更多因素都会导致这种行为。
如果你想获得“更好”的结果,你应该多运行一次,然后取平均值。
这就是为什么您应该知道如何使用Java对事物进行基准测试,请参阅How do I write a correct micro-benchmark in Java?。
答案 2 :(得分:4)
JVM花了一些时间来初始化所有需要的对象,访问系统时间,系统输出流等......你有两种方法发生在:
System.nanoTime()
System.out.println()
每个人都可以执行很多初始化代码。)
每次连续呼叫都要快得多,因为这已经完成了。因此,当人们对性能应用程序进行基准测试时,通常会放弃预热和冷却阶段(例如,第一次和最后15分钟)。