• 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

     上面并行之所以慢是因为数据要进行拆箱装箱操作,所以用LongStream替代Stream就可以提升程序的效率.

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

  • 相关阅读:
    C. MP3(离散化 暴力)
    最大团、最小独立集
    欧拉函数
    In Touch(dijk+并查集优化)
    Path(2019 杭电多校第一场 ) hdu 6582(最短路模板+dinic模板)
    2019 南昌邀请赛 Winner (tarjan缩点)
    mybatis主键回填和自定义
    mybatis配置xml文件的层次结构
    Paratroopers
    Dual Core CPU
  • 原文地址:https://www.cnblogs.com/lishuaiqi/p/12075498.html
Copyright © 2020-2023  润新知