繁体   English   中英

Java-执行时间

[英]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的粒度很高。 加上操作系统的负载,这将意味着您在测量中的实验误差远大于结果本身的大小。
  • 即使发生了添加,您也没有“预热” VM。 通常,由于这个原因,您放第二个操作都会更快。

潜伏着更多的潜在危害。

故事的寓意是在现实条件下测试您的代码 ,以查看其行为方式。 孤立地测试小部分代码并假定总体性能将是这些部分的总和,这绝对不准确。

首先 Java编译器执行常量表达式的优化,因此您的代码在编译时将转换为:

int b = 120;

结果,JVM几乎同时执行了对a=20b=120分配。

第二 您对大型系统进行简短测量(我的意思是包括操作系统,交换进程,另一个运行进程...的整个计算机)。 因此,您可以在非常短的时间内获得随机系统的快照。 这就是为什么你不能推断真或假的那a任务是要快b 为了证明这一点,您必须将代码测量置于相当大的循环中-大约重复进行1,000,000次。 如此大的重复次数可以让您放宽期望(从这个词的数学意义上来说)

这不是衡量性能的正确方法。

首先,不要测量这么小的代码。 而是像@NilsH所建议的那样调用它数百万次,然后通过将经过的时间除以调用次数来获得平均时间。

其次,JVM可能会对您的代码执行优化,因此您需要给它一个“热身”时间。 在开始测量之前,使数百万人“不运行”,而根本不计时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM