• Stream的并行计算


    一、Stream并行计算体验,利用多核加快计算速度

    stream的并发,多个cpu执行同一个任务,提高效率;

    需求:从1+...+10000000,看下各种计算方法的运行时间是多少

    代码例子如下:

      1 package com.cy.java8;
      2 
      3 import java.util.function.Function;
      4 import java.util.stream.LongStream;
      5 import java.util.stream.Stream;
      6 
      7 public class ParallelProcessing {
      8 
      9     public static void main(String[] args) {
     10         //查看计算机核心线程数
     11         //System.out.println(Runtime.getRuntime().availableProcessors());
     12 
     13         long fastest1 = measureSumPerformance(ParallelProcessing::normalAdd, 10000000);
     14         System.out.println("normalAdd the best processing time : " + fastest1 + " ms");
     15 
     16         long fastest2 = measureSumPerformance(ParallelProcessing::iterateStream, 10000000);
     17         System.out.println("iterateStream the best processing time : " + fastest2 + " ms");
     18 
     19         long fastest3 = measureSumPerformance(ParallelProcessing::parallelStream, 10000000);
     20         System.out.println("parallelStream the best processing time : " + fastest3 + " ms");
     21 
     22         long fastest4 = measureSumPerformance(ParallelProcessing::parallelStream2, 10000000);
     23         System.out.println("parallelStream2 the best processing time : " + fastest4 + " ms");
     24 
     25         long fastest5 = measureSumPerformance(ParallelProcessing::parallelStream3, 10000000);
     26         System.out.println("parallelStream3 the best processing time : " + fastest5 + " ms");
     27 
     28     }
     29 
     30 
     31     /**
     32      * 将下面的求和方法分别计算10次,取10次中运行最短的时间
     33      */
     34     private static long measureSumPerformance(Function<Long, Long> adder, long limit){
     35         long fastest = Long.MAX_VALUE;
     36 
     37         for(int i=0; i<10; i++){
     38             long startTime = System.currentTimeMillis();
     39             long result = adder.apply(limit);
     40             long spendTime = System.currentTimeMillis() - startTime;
     41             System.out.println("the sum result is " + result);
     42             if(spendTime < fastest){
     43                 fastest = spendTime;
     44             }
     45         }
     46         return fastest;
     47     }
     48 
     49     /**
     50      * 计算一串long类型的总和,普通的stream
     51      * @param limit
     52      * @return
     53      */
     54     private static long iterateStream(long limit){
     55         return Stream.iterate(1L, i->i+1).limit(limit).reduce(0L, Long::sum);
     56     }
     57 
     58     /**
     59      * 使用Stream.parallel
     60      * 比较慢,为什么?
     61      * Stream.iterate不适合并行计算
     62      */
     63     private static long parallelStream(long limit){
     64         return Stream.iterate(1L, i->i+1).parallel().limit(limit).reduce(0L, Long::sum);
     65     }
     66 
     67     /**
     68      * 将上面的Stream先自动拆箱为long,再并行
     69      * 虽然拆箱为LongStream,还是很慢,为什么?
     70      * Stream.iterate不适合并行计算
     71      */
     72     private static long parallelStream2(long limit){
     73         return Stream.iterate(1L, i -> i + 1)
     74                         .mapToLong(Long::longValue)
     75                         .parallel().limit(limit).reduce(0L, Long::sum);
     76     }
     77 
     78     /**
     79      * 使用LongStream.range
     80      * 很快,比normalAdd快了近一倍,为什么?
     81      * LongStream、IntStream等..它们的IntStream.range非常卓越的适合并行计算
     82      */
     83     private static long parallelStream3(long limit){
     84         return LongStream.rangeClosed(1, limit).parallel().reduce(0L, Long::sum);
     85     }
     86 
     87 
     88     /**
     89      * 以前的写法
     90      * @param limit
     91      * @return
     92      */
     93     private static long normalAdd(long limit){
     94         long result = 0L;
     95         for(long i=0L; i <= limit; i++){
     96             result += i;
     97         }
     98         return result;
     99     }
    100 }

    console:

    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    normalAdd the best processing time : 3 ms
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    iterateStream the best processing time : 78 ms
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    parallelStream the best processing time : 128 ms
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    parallelStream2 the best processing time : 178 ms
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    the sum result is 50000005000000
    parallelStream3 the best processing time : 0 ms

    结论:不一定是所有的方法产生的Stream都适合于并行的方式去做的,一定要注意有些方法是对于并行是厌恶的,有些方法是喜欢并行的;

    列举一些例子如下:

    数据源           分解性能
    Source           Decomposability
    ArrayList           Excellent
    LinkedList           Poor
    IntStream.range        Excellent
    Stream.iterate         Poor
    HashSet             Good
    TreeSet              Good

    ----

  • 相关阅读:
    新手学习FFmpeg
    新手学习FFmpeg
    新手学习FFmpeg
    进阶计划
    面试题汇总
    grep命令
    Quartz教程三:Job与JobDetail介绍
    spring boot热部署
    Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(四)
    SpringBoot集成篇(二) 异步调用Async
  • 原文地址:https://www.cnblogs.com/tenWood/p/11569235.html
Copyright © 2020-2023  润新知