点击蓝色“程序猿DD”关注我

回复“资源”获取独家整理的学习资料!

作为技术人员,学习新知识是基本功课。有些知识是不得不学,有些知识是学了之后如虎添翼,Java8的Stream就是兼具两者的知识。不学看不懂,学了写起代码来如虎添翼。

在上篇《当只用一行代码就搞定最终结果时,是不是再也不想用for循环一遍遍去迭代了。

同时,你是否又看到类似《Java8 Lambda表达式和流操作如何让你的代码变慢5倍》这样的文章,那么今天就带大家通过编写测试程序来一探究竟,看看Stream的性能到底如何。同时,带大家认识一个非常不错的性能测试工具junitperf。

测试环境

先同步一下测试环境及工具信息:

  • JDK版本:1.8.0_151。

  • 电脑配置:MacBook Pro i7,16G内存。

  • Java测试工具:junitperf及Junit。

  • IDE:intellij IDEA。

在测试的过程中电脑中还开了其他很多应用,但基本上都没进行操作。

实验一:基本类型迭代

基本测试方案,先初始化一个int数组,5亿个随机数。然后从这个数组中找到最小的一个数。

采用三个单元测试方法来对照参考:

  • testIntFor方法测试for循环执行时间;

  • testIntStream方法测试串行Stream执行时间;

  • testIntParallelStream方法测试并行Stream执行时间;

测试程序相关代码:

public class StreamTest {   public static int[] arr;    @BeforeAll public static void init() { arr = new int[500000000];  randomInt(arr); }   @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})  public void testIntFor() {  minIntFor(arr); }   @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})  public void testIntParallelStream() {   minIntParallelStream(arr);  }   @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})  public void testIntStream() {   minIntStream(arr);  }   private int minIntStream(int[] arr) {   return Arrays.stream(arr).min().getAsInt(); }   private int minIntParallelStream(int[] arr) {   return Arrays.stream(arr).parallel().min().getAsInt();  }   private int minIntFor(int[] arr) {  int min = Integer.MAX_VALUE;   for (int anArr : arr) { if (anArr < min) {   min = anArr;   }   }   return min; }   private static void randomInt(int[] arr) {  Random r = new Random();   for (int i = 0; i < arr.length; i++) {    arr[i] = r.nextInt();  }   }
}

基本操作流程:通过@BeforeAll注解的init方法对数组进行随机初始化,然后再统一执行上面三个方法。

在单元测试的方法上都有下面的注解:

@JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})

该注释为junitperf提供的注解,其中duration为持续执行这段代码的时间,单位毫秒;warmUp预热时间,这里预热1秒;reporter输出报表格式,这里采用HTML展示,可以更直观看到效果。

好上面的一切都准备好了,剩下的就是统一执行单元测试。执行结果如下三个图。

针对基础类型(int)操作,结果分析:

  • 串行Stream的执行的确不如for循环性能高,耗时大概是for循环的2倍。

  • 并行Stream的执行性能要优于for循环,耗时大概是for循环的一半。

  • 这里没有用不同核数的机器测试,但并行Stream随着服务器核数的增加,必然更快。

实验二:对象迭代

生成一个List列表,列表中随机生成1千万个字符串,然后分别通过不同的方式计算获得最小的字符串。基本操作与实验一相同,不再贴出代码,直接看测试的效果图。

针对对象(String)操作,结果分析:

  • Stream的性能与for循环已经相差不大了,耗时大概是for循环的1.25倍左右。

  • 并行Stream执行的性能要优于for循环,而且比基础类型的优势更高,耗时已经低于for循环的一半。

  • 针对不同服务器核数,Stream效率同样会更加高。

实验三:复杂对象归约

生成一个List列表,列表里面存放着1百万个User对象。每个对象中都包含用户名和用户某次运动的距离,同一用户可在List里包含多条运动记录。现在通过不同的方式来统计用户的总共运动了多远距离。

基本测试思路一致,这里只贴出基于Stream的算法的代码,以便大家了解Stream的复杂对象归约如何使用。

// 串行写法
users.stream().collect( Collectors.groupingBy(User::getUserName,    Collectors.summingDouble(User::getMeters)));
// 并行写法
users.parallelStream().collect( Collectors.groupingBy(User::getUserName,    Collectors.summingDouble(User::getMeters)));

下面看测试结果的数据:

复杂对象归约操作,结果分析:

  • 基于Stream的操作明显都高于for循环的效率,而且并行的效果更加明显。

  • 同样,随着服务器核数的增加,并行Stream的效率会更高。

最后推荐一下这款用起来还不错的Java性能测试工具,GitHub地址:https://github.com/houbb/junitperf。 上面有详细的使用说明。唯一缺少的就是数据预初始化的示例,而本篇文章的示例中已经补上了这部分缺失。

小结

通过上面的几组实验对比,我们可以看到如下结论:

  • 针对简单的操作,比如基础类型的遍历,使用for循环性能要明显高于串行Stream操作。但Stream的并行操作随着服务器的核数增加,会优于for循环。

  • 针对复杂操作,串行Stream性能与for循环不差上下,但并行Stream的性能已经是无法匹敌了。

  • 特别是针对一个集合进行多层过滤并归约操作,无论从写法上或性能上都要明显优于for循环。

用一句话来说就是:简单操作for循环即可,复杂操作首推Stream

现在的Stream书写简单,性能不错,如果未来JDK针对其进行优化,便同时享受了便捷和性能,何乐而不为呢。

本文通过OpenWrite的免费Markdown转换工具发布

-END-

留言交流不过瘾

关注我,回复“加群”加入各种主题讨论群

朕已阅 

Java8 Stream性能如何及评测工具推荐相关推荐

  1. 【转载】浏览器测试工具有哪些 浏览器安全性能内核兼容测试工具推荐

    浏览器测试工具有哪些 浏览器安全性能内核兼容测试工具推荐 时间:2019-03-01 15:12  来源:未知   作者:浏览器家园    浏览器测试工具有哪些 浏览器安全性能内核兼容测试工具推荐 好 ...

  2. java sort 效率_性能对比:collections.sort vs treeSet sort vs java8 stream.sorted

    0 写在前面的话 在项目中有一个排序问题,考虑到未来需要排序的数据量可能很大,想用一个性能较好的排序算法,现在有三套解决方法:jdk提供的集合的sort方法(Collections.sort).一个可 ...

  3. linux下性能测试mon,Linux性能评测工具之一:nmon篇

    1.nmon概述 1.1.概述 nmon是收集AIX或Linux主机的性能数据并分析的工具,使用简单易用.主要有两个,一个是nmon采集数据的工具,一般名称为nmon_**,例如nmon_aix5.3 ...

  4. 前端利器,6 款开源 Web 性能优化辅助工具推荐

    转自:原文链接 Web 性能优化是一个老生常谈的话题,也是前端页面开发十分重要的部分.当页面加载速度越慢,用户流失的概率就越大,性能和交互直接影响用户体验. 下面推荐几款 Web 性能优化辅助工具推荐 ...

  5. 全网最全的知识库管理工具综合评测和推荐:FlowUs、Baklib、简道云

    全网最全.最佳的知识库管理工具综合评测和推荐:FlowUs.Baklib.简道云.ONES Wiki .PingCode.Seed.MeBox.亿方云.智米云.搜阅云.天翎 知识库的发展路径 知识库主 ...

  6. java8函数式编程 视频_快速掌握Java8 Stream函数式编程技巧

    函数式编程优势"函数第一位",即函数可以出现在任何地方. 可以把函数作为参数传递给另一个函数,还可以将函数作为返回值. 让代码的逻辑更清晰更优雅. 减少了可变量(Immutable ...

  7. 10大主流压力测试工具推荐(转载)

    在移动应用和Web服务正式发布之前,除了进行必要的功能测试和安全测试,为了保证互联网产品的服务交付质量,往往还需要做压力/负载/性能测试.然而很多传统企业在试水互联网+的过程中,往往由于资源或产品迭代 ...

  8. 简洁又快速地处理集合——Java8 Stream(下)

    上一篇文章我讲解 Stream 流的基本原理,以及它与集合的区别关系,讲了那么多抽象的,本篇文章我们开始实战,讲解流的各个方法以及各种操作 没有看过上篇文章的可以先点击进去学习一下 简洁又快速地处理集 ...

  9. java excel 插件开发工具_程序员常用的15 种开发者工具推荐

    程序员常用的15 种开发者工具推荐:Java 线上诊断工具 Arthas.IDE 插件 Cloud Toolkit.混沌实验注入工具 ChaosBlade.Java 代码规约扫描插件.应用实时监控工具 ...

最新文章

  1. 如何把 XML 文件显示为 HTML 表格
  2. C++实现遍历链表一次求出中间的节点
  3. 【斗医】【10】Web应用开发20天
  4. ADS的go to命令
  5. 利用python进行识别相似图片(二)
  6. 指明方向与趋势!2019开发者技能报告出炉!!!
  7. 语义分析 文本矛盾点解析_关于解析文本的几点思考
  8. unity 解决引入dlopen api的问题
  9. python3怎么安装gmpy2_python2/3 模块gmpy2在linux下安装
  10. 在集设|参透海报设计中提取排版设计灵感
  11. mongoDB - 插入数据
  12. 一些用CRF做图像语义分割的资源
  13. 白盒测试哪种测试效果好_比较常用的白盒测试工具有哪些?
  14. java运行方法_java程序怎么运行?java程序运行方法
  15. 没有任何借口——提升职场能力的文章
  16. c# 连接 oracle数据库字符集为us7ascii的问题,实验了好几个方案 成功了
  17. QScrollBar垂直滚动条简单样式定制
  18. 数据治理与数据安全研读开篇
  19. 同余概述(同余定理)
  20. 如何鉴定游戏音效侵权行为?

热门文章

  1. linux 挂载错误 mount: unknown filesystem type LVM2_member 解决方法
  2. linux 服务管理两种方式service和systemctl
  3. Nginx之location 匹配规则详解
  4. 驱动WDK7600在VC6.0下的编译开发配置环境
  5. UNIX--更改/输出当前工作目录
  6. openstack nova-compute 组件无法启动
  7. 表单源码php,PHP微信表单源码解密开源版 微擎原版功能模块 多功能表单 微信万能表单2.8WEUI高级版...
  8. 数据结构 - 二叉排序树
  9. oracle23290,详细介绍Oracle数据库EM Console重建过程
  10. java求平均值过程不输入,java-Flink:有没有其他方法来计算平均值和一个状态变量,而不是使用RichAggregateFunction?...