Java 为什么第一个电话这么长?

Java 为什么第一个电话这么长?,java,jit,Java,Jit,我发现某些函数的第一次调用花费的时间太长。 下面是我的简单测试: 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); Sy

我发现某些函数的第一次调用花费的时间太长。 下面是我的简单测试:

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;
    }
}
你能给我解释一下为什么会这样吗?或者一些我能找到答案的资源。它可以连接到JIT,但我不确定这一点

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

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

这里有两个方面:

  • 你的基准基本上是有缺陷的,而且是一团糟的。你想读书
  • 是的,JIT需要一个
简单地说:在运行时,JIT观察您的代码在做什么。它应用了触发优化调用的启发式方法。因此:不要期望确定性行为。很难得到真正有意义的数字


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

调用
nanoTime
可能比您正在测试的代码花费更长的时间……事实上,我只是简化了代码。我在运行时集成groovy脚本时发现了这种行为,然后尝试上面的代码——相同的行为。可能重复的“否”,当然不是。为什么你认为它是重复的?我一点也不想做基准测试!它几乎是重复的,因为你的第一个问题是你不知道如何生成有意义的数字。除此之外:我感谢你的快速接受!Tbh,这个问题是你链接的副本,就像NPE问题一样。@GhostCat谢谢你的回答。帮助链接到热身。这根本不是基准。我没有尝试进行精确的测量。我了解这种行为,并试图找出原因。
# Warmup Iteration   1: 179791124,395 ops/s
# Warmup Iteration   2: 183962412,435 ops/s
# Warmup Iteration   3: 284320650,805 ops/s