Java - 执行时间

时间:2013-06-03 09:59:23

标签: java time invoke 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);

}

使用此输出/ s:
测试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;快?

3 个答案:

答案 0 :(得分:5)

众所周知,微型计算机很难做到正确,特别是在Java等“智能”语言中,编译器和Hotspot可以进行大量的优化。你几乎肯定没有测试你认为你正在测试的东西。阅读Anatomy of a Flawed Microbenchmark以获取更多详细信息和示例(现在这是一篇相当古老的文章,但原则与以往一样有效)。

在这种特殊情况下,我至少可以看到三个问题:

  • 代码根本不会执行任何添加,因为编译器会为变量分配编译时常量值。 (即,就好像您的代码为int a = 20;int b = 120;
  • 大多数系统上nanoTime的粒度非常高。这与OS的负载相结合,意味着您在测量中的实验误差远远大于结果本身的大小。
  • 即使正在进行添加,也没有“预热”VM;通常情况下,您放置的第二个操作会因此而显得更快。

潜伏的潜在危险也可能更多。

故事的寓意是在真实条件下测试您的代码,以了解它的行为方式。单独测试小块代码并假设整体性能将是这些代码的总和是不准确的。

答案 1 :(得分:4)

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

int b = 120;

结果,JVM几乎在同一时间执行a=20b=120分配。

第二个。你执行大系统的短测量(我的意思是包括操作系统,交换过程,另一个运行过程的整个计算机......)。因此,您可以在非常短的时间段内获得随机系统的快照。这就是为什么你不能推断a作业比b更快的真假。为了证明这一点,你必须将代码测量放在相当大的循环中 - 做大约1,000,000次。如此大的重复可以让你平滑期望(在这个词的数学意义上)

答案 2 :(得分:2)

这不是衡量效果的正确方法。

首先,不要测量这么小的代码。 相反,像@NilsH建议的那样,将其称为数百万次, 并通过将经过的时间除以通话次数来获得平均时间。

其次,JVM可能会对您的代码执行优化, 所以你需要给它一个“热身”的时间。 在没有测量时间的情况下,让几百万人“干”运行, 而不是开始你的测量。