【问题标题】:Why first call is so long?为什么第一次通话这么长?
【发布时间】:2017-05-24 09:21:01
【问题描述】:

我发现某些函数的第一次调用耗时太长。 这是我的简单测试:

public class MainTest {
    public static void main(String[] args) {
        long k = 0;
        for (int i = 0; i < 10; i++) {
            long start = System.nanoTime();
            k += doWork(i);
            System.out.println(System.nanoTime() - start);
        }
        System.out.println(k);    
    }

    public static long doWork(long var) {
        for (int i = 0; i < 100000; i++) {
            var += i;
        }
        return var;
    }
}

结果:

820521
283961
292514
259442
88952
86100
82965
81539
74126
29651

你能给我一些关于为什么会发生的版本吗?或者一些我可以找到答案的资源。可以用JIT连接,但我不确定。

我知道 nanotime 不适合测试。我试试 JMH:

# Warmup Iteration   1: 179791124,395 ops/s
# Warmup Iteration   2: 183962412,435 ops/s
# Warmup Iteration   3: 284320650,805 ops/s

【问题讨论】:

  • nanoTime 的调用可能需要比您正在测试的代码更长的时间...
  • 其实我只是简化了代码。我在运行时集成 groovy 脚本时发现了这种行为,然后尝试上面的代码 - 相同的行为。
  • 不,当然不是。为什么你认为它是重复的?我根本不想进行基准测试!
  • 这接近于重复,因为您的第一个问题是您不了解如何生成有意义的数字。除此之外:感谢您的快速接受!

标签: java jit


【解决方案1】:

这里有两个方面:

  • 您的基准基本上是有缺陷和搞砸的。你想阅读this
  • 是的,JIT 需要 warm up

简单地说:在运行时,JIT 会观察您的代码在做什么。它应用触发优化调用的启发式。因此:不要期望确定性行为。 很难得到真正有意义的数字。

为了获得更可靠的结果,您必须显着提高“测量”过程的质量。

【讨论】:

  • Tbh,这个问题与您的链接重复,就像 NPE 问题一样。
  • @GhostCat 感谢您的回答。帮助链接到热身。它根本不是基准。我没有尝试进行准确的测量。我得到了这种行为,并试图找出为什么会这样。
猜你喜欢
  • 2022-07-21
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 2017-07-02
  • 1970-01-01
  • 2011-01-03
相关资源
最近更新 更多