以前写过的一个并行流Demo,记得当初一个群里的小朋友非说并行流执行快,我较真的测试了一次,然而现实说明,没有亲自试验过的说法永远都是不可信的。
虽然我这个逻辑并不能真正的证明实际业务中并行流一定不如基础方法,但是在一定程度上的表达了新技术方案不是随便就可以使用的。
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* @author yongqi.wang
* @version 类说明:计算一到一百万相加
*/
public class test {
public static void main(String[] args) {
int i = 1;
List<Long> lists = new ArrayList<>();
for (long l = 0L; l < 1000000; l++) {
lists.add((long) (i += 1L));
}
long currentTimeMillis = System.currentTimeMillis();
Optional<Long> reduce = lists.parallelStream().reduce((a, b) -> a + b);
long currentTimeMillis2 = System.currentTimeMillis();
if (reduce.isPresent())
System.out.println("并行流执行时间:" + (currentTimeMillis2 - currentTimeMillis) + "\t结果:" + reduce.get());
long sum = 0;
long currentTimeMillis3 = System.currentTimeMillis();
for (Long num : lists) {
sum += num;
}
long currentTimeMillis4 = System.currentTimeMillis();
System.out.println("foreach执行时间:" + (currentTimeMillis4 - currentTimeMillis3) + "\t结果:" + sum);
}
}
第一次执行:
并行流执行时间:109 结果:500001500000
foreach执行时间:13 结果:500001500000
第二次执行:
并行流执行时间:119 结果:500001500000
foreach执行时间:14 结果:500001500000
第三次执行:
并行流执行时间:109 结果:500001500000
foreach执行时间:10 结果:500001500000
但是,一旦你的业务逻辑比较复杂时,那么它就会体现出他的优势,单个业务逻辑200毫秒可以说不是很慢了
public class test {
public static void main(String[] args) {
int i = 1;
List<Long> lists = new ArrayList<>();
for (long l = 0L; l < 1000; l++) {
lists.add((long) (i += 1L));
}
long currentTimeMillis = System.currentTimeMillis();
Optional<Long> reduce = lists.parallelStream().reduce((a, b) -> {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return a + b;
});
long currentTimeMillis2 = System.currentTimeMillis();
if (reduce.isPresent())
System.out.println("并行流执行时间:" + (currentTimeMillis2 - currentTimeMillis) + "\t结果:" + reduce.get());
long sum = 0;
long currentTimeMillis3 = System.currentTimeMillis();
for (Long num : lists) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
sum += num;
}
long currentTimeMillis4 = System.currentTimeMillis();
System.out.println("foreach执行时间:" + (currentTimeMillis4 - currentTimeMillis3) + "\t结果:" + sum);
}
}
结果:
并行流执行时间:50403 结果:501500
foreach执行时间:200501 结果:501500
下面来看一下它的实现源码
第一个方法,来自Collollection的default方法
/**
* 这个方法表示以本集合为数据源,返回一个可并行的顺序流
* 并且这个方法的执行权重大于spliterator()方法,而且它不能返回一个不可变得、同步的或延迟绑定的流
* 默认实现从集合spliterator()方法获取一个并行流
* 并行流运行结束返回这个集合中的元素
*/
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
然后StreamSupport.stream方法使用了spliterator()方法的返回值作为方法参数之一,那么首先看看spliterator方法的内容
/**
* 首先他覆盖了父类Itrable中的default方法实现
* 调用了Spliterators的方法使用自己为方法参数构建IteratorSpliterator对象
* 而父类中的方法实现时使用了集合对应的迭代器作为方法参数构建IteratorSpliterator对象。
*/
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
那么下一步就是StreamSupport的stream方法实现了
/**
* 这个方法用于创建新的顺序或并行流,主要取决于spliterator对象的实现类
* 到了这里我们就可以分析出,如果使用的是迭代器构建的子类那么应该就是顺序流
* 如果使用自身,那么构建的就是一个并行流
* 同时这个方法表示:本spliterator对象只有在流管道的终端操作开始后,才能遍历、拆分或
* 查询spliterator的估计大小。
*/
public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel) {
Objects.requireNonNull(spliterator);
return new ReferencePipeline.Head<>(spliterator,
StreamOpFlag.fromCharacteristics(spliterator),
parallel);
}
在之后我们看一下StreamOpFlag的fromCharacteristics查询了这个拆分器的哪个特性用作构建Head的参数。
/**
* 这个具体实现大家可以自行看看,反正我对于二进制运算比较蒙圈~~
*/
static int fromCharacteristics(Spliterator<?> spliterator) {
int characteristics = spliterator.characteristics();
if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) {
// Do not propagate the SORTED characteristic if it does not correspond
// to a natural sort order
return characteristics & SPLITERATOR_CHARACTERISTICS_MASK & ~Spliterator.SORTED;
} else {
return characteristics & SPLITERATOR_CHARACTERISTICS_MASK;
}
}
//ArrayListSpliterator 的 characteristics方法实现
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
最后stream使用了这三个参数构建了这么一个对象,当然构建的是这个抽象类的子类,但是子类没有做其他的修改操作,所以我还是吧父类的构造方法放在这里了。
AbstractPipeline(Spliterator<?> source,
int sourceFlags, boolean parallel) {
this.previousStage = null;
this.sourceSpliterator = source;
this.sourceStage = this;
this.sourceOrOpFlags = sourceFlags & StreamOpFlag.STREAM_MASK;
// The following is an optimization of:
// StreamOpFlag.combineOpFlags(sourceOrOpFlags, StreamOpFlag.INITIAL_OPS_VALUE);
this.combinedFlags = (~(sourceOrOpFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE;
this.depth = 0;
this.parallel = parallel;
}
最后的reduce()方法就没什么好说的了,它是一个函数式调用的方法,其中使用了断言和数据多维运算模型计算,反正我是只看了一点皮毛,说了也不一定对,就略过了~~
长期以来MySQL官方都缺少原生的MySQL集群多活且能提供强一致性的解决方案,所以第三方公司基于Galera协议的Percona XtraDB Cluster(PXC)积累了很多客户案例。 2016年12月12日Oracle发布了MySQL Group Replication的首个GA版本,并且提供了自家对比Galera的性能测试。MGR作为官方力推的明星产品,的确具备了与市场老牌产品(如PXC)竞争的资格。MGR是基于Paxos分布式一致性协议的高可用解决方案,完美地解决了MySQL在一致性与高可用方面_精通mysql调优
一、卷积只能在同一组进行吗?– Group convolutionGroup convolution 分组卷积,最早在AlexNet中出现,由于当时的硬件资源有限,训练AlexNet时卷积操作不能全部放在同一个GPU处理,因此作者把feature maps分给多个GPU分别进行处理,最后把多个GPU的结果进行融合。AlexNet分组卷积的思想影响比较深远,当前一些轻量级...
seaborn —— 课后练%matplotlib inlineimport numpy as npimport pandas as pdfrom scipy import stats, integrateimport matplotlib as mplfrom matplotlib import pyplot as pltimport seaborn as sns练习1:鸢尾花花型尺寸分析鸢尾..._练习1:鸢尾花花型尺寸分析
数论是纯粹数学的分支之一,主要研究整数的性质。按研究方法来看,数论大致可分为初等数论和高等数论。初等数论是用初等方法研究的数论,它的研究方法本质上说,就是利用整数环的整除性质,主要包括整除理论、同余理论、连分数理论。高等数论则包括了更为深刻的数学研究工具。它大致包括代数数论、解析数论、计算数论等等。在竞赛领域常常用到的是数论有关的一些数论基础与定理的运用。...
从当前看到的情况是,已经开始春招了。往年都是奔波宣讲会,但是今年应该还是会收敛很多,主要以现场面试,电话面试,线上投递,发放offer。但是,核心内容是不变动的。这也是我一直在文章中提到的,校招该准备哪些内容呢?1 学习成绩学习成绩非常关键,这个决定了你投递的简历,对方是否乐意招你。一般而言,简单的推论就是,学习能力强,至少证明了大学期间没有荒废学业,重视大学学业。很多人忽略了这一点,认为只要有本事,就可以。这个就大错特错了。在大学期间,4 6 级考试真的非常重要,这点在你找工作的时候,就是_为什么每年春招都不一样
鸿蒙系统(HarmonyOS)是基于微内核的全场景分布式OS,鸿蒙OS实现模块化耦合,对应不同设备可弹性部署,鸿蒙OS有三层架构,第一层是内核,第二层是基础服务,第三层是程序框架,鸿蒙OS底层由鸿蒙微内核、Linux内核、Lite OS组成华为鸿蒙2.0开发文档及API鸿蒙开发者官网https://developer.harmonyos.com/cn/home鸿蒙应用开发文档https://developer.har..._鸿蒙编程
“成语小博士”是一款快捷查找成语的工具类应用程序。提供了“按拼音”、“按汉字”、“按词义”、“按特殊结构”四种模糊查询成语的方法。应用收录了近三万个常用的成语词目。为弘扬中华文化,本应用将永久免费。 本隐私策略声明函盖了用户对于“成语小博士”应用程序中所有内容的使用。 “成语小博士”不会收集、存储、分享用户的任何个人信息;也不会收集、存储、分享用户用于安装本应用的设备相关的信息。_微软天气供应商隐私可以全部拒绝吗
周洪立是我们的CCO(首席版权官),我一直尊称他为周老师,不仅因为他德高望重、阅历丰富;更因为他已经60多岁了,但对待SDL的事业充满激情,比大部分年轻同事有过之而无不及。 从下面的一篇报道可以体会到,所以我转载于此。 ------------------------------------------------- 链接:http://www.techweb.com.cn/colum_周洪立
Python命令行清屏方法命令:>>> import os>>> os.system("clear")运行结果:..._python 命令行 清空窗口
但是这里有魔力,在扩展数据集时,你的类之间现在有更明显的界限,SVM算法能够计算出更加优化的超平面。接下来,假设你是一个农民,你有一个问题-你需要设置一个围栏,以保护你的奶牛免受狼的攻击。人工智能是计算机科学的一个分支,它企图了解智能的实质,可以产出一种新的可以和人类智能相似的方式做出反应的智能机器,该领域的研究主要有机器人、语言识别、图像识别、自然语言处理和专家系统等。自从人工智能诞生以来,理论和技术越来越成熟,应用领域在不断的扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。..._人工智能的常用算法及应用
公众号后台回复“图书“,了解更多号主新书内容作者:叶庭云来源:修炼Python一、简介Jupyter Notebook是一个开源的 Web 应用,能够让你创建、分享包含可执行代码、可视化结...
第二阶段部署UBOOT,uImage,rootfs到TF卡中准备一张TF卡,最好是金士顿的TF卡,我一开始用的不是金士顿的卡,总是部署失败,后来我换了一张32G的金士顿TF卡,成功部署!像一般的金士顿1G,2G卡也没应该有问题。1.2.1烧写UBOOT到TF卡插入TF卡,ubuntu12.04会识别。在驱动文件下可以看到/dev/sdc,文件。有些会识别成/dev/sdb,根据自己的系