Java Stream的运行速度比for循环慢

问题描述 投票:0回答:1

有人告诉我Java Stream是处理大量数据的不错选择,我最近进行了比较测试。但是测试结果出乎意料:

问题来自CodeWar:

假设最初有一个100人的地铁,在每个站点上都有几个人进入地铁而有几个人出来。目标是计算经过大量停车(100000)之后仍留在地铁中的人数。

这是我的代码:

import java.util.ArrayList;

public class Metro1 {
    private final static int STOPS = 100000;
    private static ArrayList<int[]> metro = new ArrayList<int[]>();

    public static int sum1() {
        int sum = 0;
        for(int[] x: metro) {
            sum +=x[0] - x[1];
        }
        return sum;
    }

    public static int sum2() {
        return metro.stream()
                .mapToInt(x -> x[0]-x[1])
                .sum();
    }
    public static void main(String[] args) {
        long start=0;
        long end = 0;
        metro.add(new int[] {100,0});
        for(int i=1;i<STOPS;i++) {
            int in = (int) Math.round(Math.random() * 10);
            int out = (int) Math.round(Math.random() * 10);
            metro.add(new int[] {in,out});
        }
        System.out.println("Stops: " + metro.size());

        start = System.currentTimeMillis();
        System.out.println("sum1: " + sum1());
        end = System.currentTimeMillis();
        System.out.println("sum1 (for loop): " + String.valueOf(end-start) + " milliseconds.");


        start = System.currentTimeMillis();
        System.out.println("sum2: " + sum2());
        end = System.currentTimeMillis();
        System.out.println("sum1 (stream): " + String.valueOf(end-start) + " milliseconds.");

    }

}

我在Eclipse中运行了代码,发现sum1比sum2快得多:

Stops: 100000
sum1: 79
sum1 (for loop): 6 milliseconds.
sum2: 79
sum1 (stream): 68 milliseconds.

我以为代码很简单,但是为什么流比for循环慢?

谢谢,

Alex

java algorithm stream
1个回答
1
投票

就像regexes中特定的本地解析器可以更快,那里的流提供了一种快速而简洁的数据处理方法。流的优点之一是在处理元素时可以使中间数据结构最小化。另一个是注释中已经提到的parallel方面。

但是关于您的例子。

  • 仅依靠使用内部时钟的性能测试(即使我也这样做)不是准确评估性能的最佳方法。使用Java Microbench Harness之类的东西进行测试。
  • 关于您的结果,请尝试以下操作:

    • STOPS更改为100_000_000
    • 将您的信息流修改为return metro.stream().parallel() .mapToInt(x -> x[0]-x[1]) .sum();

这是我的Windows, quad core i7 laptop上的结果

Stops: 100000000
sum1: -7073
sum1 (for loop): 908 milliseconds.
sum2: -7073
sum1 (stream): 518 milliseconds.

© www.soinside.com 2019 - 2024. All rights reserved.