首页 > 解决方案 > Java 中的流比原生 for 循环慢得多 - 为什么?

问题描述

据我了解,流比传统的旧编程更快。

但是,当我运行以下代码时,结果是我没想到的。

public class Application {
    public static void main(String[] args) {
        long startTime = System.nanoTime();
        int[] a = { 1, 2, 3, 4 };
        int m = Arrays.stream(a).reduce(Integer.MIN_VALUE, Math::max);
        long endTime = System.nanoTime();
        long totalTime = endTime - startTime;
        System.out.println(totalTime);

    }
}

输出为:22857304

public class Application {
        public static void main(String[] args) {
        long startTime = System.nanoTime();
        int[] a = { 1, 2, 3, 4 };
        int e = a.length;
        int m = Integer.MIN_VALUE;
        for (int i = 0; i < e; i++)
            if (a[i] > m)
                m = a[i];
        long endTime = System.nanoTime();
        long totalTime = endTime - startTime;
        System.out.println(totalTime);
    }
}

输出为:1459

请帮我理解为什么流这么慢?

标签: javajava-8java-stream

解决方案


完全解释这一点需要很多时间;但是您在这里测试的是“冷”启动,基本上没有太多JIT,而且一个简单的循环不会像 Stream 解决方案那样分配对象 - 因此时间要少得多。Streams 有一个可以运行的基础设施——这需要一段时间来“加热”以提高性能。

代码的这些部分也不等价,就像您正在使用的一样Math::max,在一个普通的>。您可以反复测试此代码并查看结果,但即便如此,您也应该使用为微基准量身定制的工具,我知道JMH(并且Caliper来自谷歌 - 但我只相信第一个)。

C1使用 JMH,您可以完全不使用 JIT、仅编译器或其他一些设置来测试这些方法C2,对于某些设置的示例,请参阅此答案


推荐阅读