Stream parallel并行流的思考

Posted lishuaiqi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Stream parallel并行流的思考相关的知识,希望对你有一定的参考价值。

1.并行流并不一定能提高效率,就和多线程并不能提高线程的效率一样

因为引入并行流会引起额外的开销,就像线程的频繁上下文切换会导致额外的性能开销一样,当数据在多个cpu中的处理时间小于内核之间的传输时间,使用并行流也就没有什么意义了.

这边用代码演示一下

public static long iterativeSum(long n) {
        long result = 0;
        for (long i = 1L; i <=n; i++) {
            result += i;
        }
        return result;
    }
public static long parallelSum(long n){
        return Stream.iterate(1L, i -> i+1)
                .limit(n)
                .parallel()
                .reduce(0L, Long::sum);
    }

 

第一个是我们经常使用的for循环,第二个是使用LongStream生成long类型的流,并且通过 parallel并行化,我们看看执行结果

 

package demo13;

import java.util.function.Function;
  
public class PerformanceClass {
    
    public static long measureSumPerf(Function<Long, Long> adder, long n) {
        long fastest = Long.MAX_VALUE;
        for (int i = 0; i < 10; i++) {
            long start = System.nanoTime();
            long sum = adder.apply(n);
            System.out.println("Result: "+ sum);
            long duration = (System.nanoTime() - start) / 1_000_000;
            if (duration < fastest) {
                fastest = duration;
            }
        }
        return fastest;
    }

    public static void main(String[] args) {
        System.out.println(measureSumPerf(ParalleStreams::iterativeSum, 10_000_000));//3
        System.out.println(measureSumPerf(ParalleStreams::parallelSum, 10_000_000));//173
//        System.out.println(measureSumPerf(ParalleStreams::sequentialSum, 10_000_000));
//        System.out.println(measureSumPerf(ParalleStreams::rangedSum, 10_000_000));
//        System.out.println(measureSumPerf(ParalleStreams::parallelRangedSum, 10_000_000));
//        System.out.println(measureSumPerf(ParalleStreams::sideEffectSum, 10_000_000));
    }
    
}

上面只是一个测试代码,我们看到for使用了 3毫秒,但是 并行流竟然使用了 173毫秒,所以parallel并不一定能提高效率

2.这边我们可以使用LongStream来直接生成long类型的数据来避免拆装箱

public static long rangedSum(long n) {
        return LongStream.rangeClosed(1, n).reduce(0L, Long::sum);
    }
        System.out.println(measureSumPerf(ParalleStreams::rangedSum, 10_000_000));//4

 

这边只使用了4毫秒,所以使用合适的数据结构比无脑的使用并行更有用.

什么高并发,大数据,不如算法和数据机构重要.

以上是关于Stream parallel并行流的思考的主要内容,如果未能解决你的问题,请参考以下文章

《Java8实战》 - 读书笔记 - Parallel Stream并行流知识

Scalaz(58)- scalaz-stream: fs2-并行运算示范,fs2 parallel processing

Scalaz(59)- scalaz-stream: fs2-程序并行运算,fs2 running effects in parallel

Jdk8新特性之Stream

stream 并行操作

Stream多线程并行数据处理