performance - Java - 重复函数调用减少执行时间

标签 performance jvm java-8 java-stream

我有以下代码

public class BenchMark {
    public static void main(String args[]) {
        doLinear();

        doLinear();

        doLinear();

        doLinear();

    }


    private static void doParallel() {
        IntStream range = IntStream.range(1, 6).parallel();

        long startTime = System.nanoTime();
        int reduce = range
                .reduce((a, item) -> a * item).getAsInt();
        long endTime = System.nanoTime();
        System.out.println("parallel: " +reduce + " -- Time: " + (endTime - startTime));
    }

    private static void doLinear() {
        IntStream range = IntStream.range(1, 6);

        long startTime = System.nanoTime();
        int reduce = range
                .reduce((a, item) -> a * item).getAsInt();
        long endTime = System.nanoTime();
        System.out.println("linear: " +reduce + " -- Time: " + (endTime - startTime));
    }

}

我试图对流进行基准测试,但在一次又一次调用相同的函数时,执行时间逐渐减少

输出:

linear: 120 -- Time: 57008226
linear: 120 -- Time: 23202
linear: 120 -- Time: 17192
linear: 120 -- Time: 17802

Process finished with exit code 0

第一次和第二次执行时间存在巨大差异

我确信 JVM 可能在幕后做一些把戏,但有人可以帮助我了解那里到底发生了什么吗?

是否有办法避免这种优化,以便我可以对真实的执行时间进行基准测试?

最佳答案

I'm sure JVM might be doing some tricks behind the scenes but can anybody help me understand whats really going on there?

  1. 第一次调用的巨大延迟是由于整个 lambda 运行时子系统的初始化造成的。您只需为整个申请支付一次费用。

  2. 当您的代码第一次到达任何给定的 lambda 表达式时,您需要为该 lambda 的链接付费(invokedynamic 调用站点的初始化)。

  3. 经过一些迭代后,由于 JIT 编译器优化了您的缩减代码,您将看到额外的加速。

Is there anyway to avoid this optimization so I can benchmark true execution time?

您在这里提出了一个矛盾:“真实”执行时间是在应用所有优化后预热后获得的执行时间。这是实际应用程序将经历的运行时。前几次运行的延迟与更广泛的情况无关,除非您对单次性能感兴趣。

为了进行探索,您可以查看禁用 JIT 编译时代码的行为方式:将 -Xint 传递给 java 命令。还有更多标志可以禁用优化的各个方面。

关于performance - Java - 重复函数调用减少执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44931750/

相关文章:

java - Stream方式获取第一个元素匹配 boolean 值的索引

java - Spark 流 : Why internal processing costs are so high to handle user state of a few MB?

java - 如何找到继承给定接口(interface)的类实例?

java - 如何在IntelliJ IDEA调试器中检查线程是否为守护线程?

java - 远程调试 Java - Solr

java - CompletableFuture 和 CountDownLatch 超时

java - DateTimeFormatter 为边缘情况提供了错误的格式

java - Python、Java 和 C 中的嵌套循环比较

c++ - 简单查询需要几分钟才能在终止/非事件 session 上执行

visual-studio-2008 - Visual Studio 数据集设计器保存速度非常慢