zoukankan      html  css  js  c++  java
  • 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毫秒,所以使用合适的数据结构比无脑的使用并行更有用.

  • 相关阅读:
    速达5000出现计算成本数据溢出的问题
    速达软件 移动端 App 功能说明
    无法打开物理文件 操作系统错误 5: 5(拒绝访问。) 问题解决
    速达软件开发版使用技巧-销售开单单据打印格式设计
    开发版速达软件如何进行有效授权
    速达软件 移动端 App 下载试用
    速达软件二次开发-试用版本下载,欢迎合作
    速达软件开发版使用技巧-每页固定行样式报表设计
    Cause: org.postgresql.util.PSQLException: 栏位索引超过许可范围:13,栏位数:12
    springboot 开启事务回滚
  • 原文地址:https://www.cnblogs.com/lishuaiqi/p/12075498.html
Copyright © 2011-2022 走看看