[英]Java - Time of execution
我有以下代码:
public static void main(String[] args) {
long f = System.nanoTime();
int a = 10 + 10;
long s =System.nanoTime();
System.out.println(s - f);
long g = System.nanoTime();
int b = 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10;
long h =System.nanoTime();
System.out.println(h - g);
}
输出结果:
测试1:
427
300
测试2:
533
300
测试3:
431
398
根据我的测试场景,为什么int b = 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10;
比int a = 10 + 10;
执行得更快int a = 10 + 10;
?
众所周知,微基准测试很难做到正确,特别是在Java等“智能”语言中,编译器和Hotspot可以进行很多优化。 几乎可以肯定,您没有测试自己认为要测试的内容。 阅读《 有缺陷的微基准测试的解剖》以获取更多详细信息和示例(这是一篇相当古老的文章,但是原理仍然有效)。
在这种特殊情况下,我马上就能看到至少三个问题:
int a = 20;
int b = 120;
) nanoTime
的粒度很高。 加上操作系统的负载,这将意味着您在测量中的实验误差远大于结果本身的大小。 潜伏着更多的潜在危害。
故事的寓意是在现实条件下测试您的代码 ,以查看其行为方式。 孤立地测试小部分代码并假定总体性能将是这些部分的总和,这绝对不准确。
首先 。 Java编译器执行常量表达式的优化,因此您的代码在编译时将转换为:
int b = 120;
结果,JVM几乎同时执行了对a=20
和b=120
分配。
第二 。 您对大型系统进行简短测量(我的意思是包括操作系统,交换进程,另一个运行进程...的整个计算机)。 因此,您可以在非常短的时间内获得随机系统的快照。 这就是为什么你不能推断真或假的那a
任务是要快b
。 为了证明这一点,您必须将代码测量置于相当大的循环中-大约重复进行1,000,000次。 如此大的重复次数可以让您放宽期望(从这个词的数学意义上来说)
这不是衡量性能的正确方法。
首先,不要测量这么小的代码。 而是像@NilsH所建议的那样调用它数百万次,然后通过将经过的时间除以调用次数来获得平均时间。
其次,JVM可能会对您的代码执行优化,因此您需要给它一个“热身”时间。 在开始测量之前,使数百万人“不运行”,而根本不计时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.