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

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

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

代码例子如下:

 package com.cy.java8;

 import java.util.function.Function;
import java.util.stream.LongStream;
import java.util.stream.Stream; public class ParallelProcessing { public static void main(String[] args) {
//查看计算机核心线程数
//System.out.println(Runtime.getRuntime().availableProcessors()); long fastest1 = measureSumPerformance(ParallelProcessing::normalAdd, 10000000);
System.out.println("normalAdd the best processing time : " + fastest1 + " ms"); long fastest2 = measureSumPerformance(ParallelProcessing::iterateStream, 10000000);
System.out.println("iterateStream the best processing time : " + fastest2 + " ms"); long fastest3 = measureSumPerformance(ParallelProcessing::parallelStream, 10000000);
System.out.println("parallelStream the best processing time : " + fastest3 + " ms"); long fastest4 = measureSumPerformance(ParallelProcessing::parallelStream2, 10000000);
System.out.println("parallelStream2 the best processing time : " + fastest4 + " ms"); long fastest5 = measureSumPerformance(ParallelProcessing::parallelStream3, 10000000);
System.out.println("parallelStream3 the best processing time : " + fastest5 + " ms"); } /**
* 将下面的求和方法分别计算10次,取10次中运行最短的时间
*/
private static long measureSumPerformance(Function<Long, Long> adder, long limit){
long fastest = Long.MAX_VALUE; for(int i=0; i<10; i++){
long startTime = System.currentTimeMillis();
long result = adder.apply(limit);
long spendTime = System.currentTimeMillis() - startTime;
System.out.println("the sum result is " + result);
if(spendTime < fastest){
fastest = spendTime;
}
}
return fastest;
} /**
* 计算一串long类型的总和,普通的stream
* @param limit
* @return
*/
private static long iterateStream(long limit){
return Stream.iterate(1L, i->i+1).limit(limit).reduce(0L, Long::sum);
} /**
* 使用Stream.parallel
* 比较慢,为什么?
* Stream.iterate不适合并行计算
*/
private static long parallelStream(long limit){
return Stream.iterate(1L, i->i+1).parallel().limit(limit).reduce(0L, Long::sum);
} /**
* 将上面的Stream先自动拆箱为long,再并行
* 虽然拆箱为LongStream,还是很慢,为什么?
* Stream.iterate不适合并行计算
*/
private static long parallelStream2(long limit){
return Stream.iterate(1L, i -> i + 1)
.mapToLong(Long::longValue)
.parallel().limit(limit).reduce(0L, Long::sum);
} /**
* 使用LongStream.range
* 很快,比normalAdd快了近一倍,为什么?
* LongStream、IntStream等..它们的IntStream.range非常卓越的适合并行计算
*/
private static long parallelStream3(long limit){
return LongStream.rangeClosed(1, limit).parallel().reduce(0L, Long::sum);
} /**
* 以前的写法
* @param limit
* @return
*/
private static long normalAdd(long limit){
long result = 0L;
for(long i=0L; i <= limit; i++){
result += i;
}
return result;
}
}

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

----

Stream的并行计算的更多相关文章

  1. java8Stream原理深度解析

    Java8 Stream原理深度解析 Author:Dorae Date:2017年11月2日19:10:39 转载请注明出处 上一篇文章中简要介绍了Java8的函数式编程,而在Java8中另外一个比 ...

  2. SQL Server-聚焦查询计划Stream Aggregate VS Hash Match Aggregate(二十)

    前言 之前系列中在查询计划中一直出现Stream Aggregate,当时也只是做了基本了解,对于查询计划中出现的操作,我们都需要去详细研究下,只有这样才能对查询计划执行的每一步操作都了如指掌,所以才 ...

  3. Java 使用 Stream API 筛选 List

    前言 上课的时候看到老师用迭代器来遍历 List 中的元素的时候,我的内心是极其嫌弃的,这种迭代方法不能直接访问当前的元素,而且写起来也麻烦.于是上网查了查 Java 有没有类似于 Linq 的东西, ...

  4. Java Stream 使用详解

    Stream是 Java 8新增加的类,用来补充集合类. Stream代表数据流,流中的数据元素的数量可能是有限的,也可能是无限的. Stream和其它集合类的区别在于:其它集合类主要关注与有限数量的 ...

  5. baike并行计算概念

    并行计算 概论 ▪ 高性能计算 ▪ 计算机集群 ▪ 分布式计算 ▪ 网格计算 ▪ 云端运算         方式 ▪ Bit-level parallelism ▪ Instruction level ...

  6. [Java 8 Lambda] java.util.stream 简单介绍

    包结构例如以下所看到的: 这个包的结构非常easy,类型也不多. BaseStream接口 全部Stream接口类型的父接口,它继承自AutoClosable接口,定义了一些全部Stream都具备的行 ...

  7. Java8 Stream简介

    Stream是Java 8新增的重要特性, 它提供函数式编程支持并允许以管道方式操作集合. 流操作会遍历数据源, 使用管道式操作处理数据后生成结果集合, 这个过程通常不会对数据源造成影响. lambd ...

  8. [三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路

    Stream的概念定义   官方文档是永远的圣经~     表格内容来自https://docs.oracle.com/javase/8/docs/api/   Package java.util.s ...

  9. [零]java8 函数式编程入门官方文档中文版 java.util.stream 中文版 流处理的相关概念

    前言 本文为java.util.stream 包文档的译文 极其个别部分可能为了更好理解,陈述略有改动,与原文几乎一致 原文可参考在线API文档 https://docs.oracle.com/jav ...

随机推荐

  1. vue学习【番外篇】vue-cli脚手架的安装

    大家好,我是一叶,今天和大家分享的是vue-cli脚手架的安装,关于vue-cli的优点,我就不赘述了. 一.检查安装node 安装vue-cli之前,先检查node是否安装.win+R,输入cmd打 ...

  2. 搜索框focus 搜索面板显示 点击别处消失 从浏览器别的页面回来消失

    开始是设置了回到页面使display:none(离开页面操作失效),但是发现回到页面,面板显示,dom获取却为null,于是做了个延时的处理 currentPage: function() { var ...

  3. TensorFlow基础与实战

    开源工具 TensorFlow:谷歌,C++.Python,Linux.Windows.Mac OS X.Andriod.iOS Caffe:加州大学,C++.Python.Matlab,Linux. ...

  4. 修改MIGO或者ML81N产生的会计凭证项目文本增强

    在程序:MM07MFF9_F_BELEG_ERGAENZEN下做隐式增强

  5. KVM安装配置笔记

    系统环境centos6.6 一.KVM安装前系统相关操作: (1)修改内核模式为兼容内核启动 # grep -v "#" /etc/grub.confdevice (hd0) HD ...

  6. 硬盘安装ubuntu遇到的问题

    终于把这个系统给装上了,陆陆续续弄了4,5天(崩溃...),一直一来都是用U盘来装ubuntu的,挺简单的,但是这个主机识别不了U盘不知道为什么...这个问题又是百度又是Google最终找不到原因只好 ...

  7. vue父组件调用子组件方法、父组件向子组件传值、子组件向父组件传值

      一.父组件调用子组件方法 父组件代码  parent.vue <template> <div> <button @click="parentFun" ...

  8. Web Api 接口测试工具:WebApiTestClient

    前言:这两天在整WebApi的服务,由于调用方是Android客户端,Android开发人员也不懂C#语法,API里面的接口也不能直接给他们看,没办法,只有整个详细一点的文档呗.由于接口个数有点多,每 ...

  9. java modCount和fail-fast

    在迭代遍历线程不安全的集合的时候,如ArrayList,如果其他线程修改了该集合,那么将抛出ConcurrentModificationException,这就是 fail-fast 策略. modC ...

  10. JVM metaspace元空间

    元空间的本质和永久代类似,都是对JVM规范中方法区的实现. 元空间不在虚拟机中,而是使用本地内存. 用于元空间的JVM参数:   -XX:MetaspaceSize=N 初始化Metaspace大小, ...