Java Stream:第2部分,计数始终是计数吗?

在上一篇有关该主题的文章中 ,我们了解到JDK 8
stream()::count需要更长的时间来执行Stream更多的元素。 对于较新的JDK(例如Java 11),简单流管道不再是这种情况。 了解JDK本身如何进行改进。

Java 8

在上一篇文章中,我们可以得出结论:
list.stream().count()在Java 8下为O(N) ,即执行时间取决于原始列表中的元素数。 阅读文章
在这里 。

Java 9及更高版本

正如Nikolai Parlog(@nipafx)和Brian Goetz(@BrianGoetz)在Twitter上正确指出的那样 ,从Java 9开始改进了Stream::count的实现。下面是对底层代码的比较
Java 8和更高Java版本之间的Stream::count代码:

Java 8(来自ReferencePipeline类)

 return mapToLong(e -> 1L).sum(); 

Java 9及更高版本(来自ReduceOps类)

 if (StreamOpFlag.SIZED.isKnown(flags)) { return spliterator.getExactSizeIfKnown();  } 
 ... 

对于Java 9和更高版本的分离器,在Java 9和更高版本中似乎出现Stream::countO(1) ,而不是O(N) 。 让我们验证该假设。

基准测试

通过在Java 8和Java 11下运行以下JMH基准可以观察到big-O属性:

 @State (Scope.Benchmark)  public class CountBenchmark { private List<Integer> list; @Param ({ "1" , "1000" , "1000000" }) private int size; @Setup public void setup() { list = IntStream.range( 0 , size) .boxed() .collect(toList()); } @Benchmark public long listSize() { return list.size(); } @Benchmark public long listStreamCount() { return list.stream().count(); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(CountBenchmark. class .getSimpleName()) .mode(Mode.Throughput) .threads(Threads.MAX) .forks( 1 ) .warmupIterations( 5 ) .measurementIterations( 5 ) .build(); new Runner(opt).run(); }  } 

这将在我的笔记本电脑(MacBook Pro 2015年中,2.2 GHz Intel Core i7)上产生以下输出:

JDK 8(来自上一篇文章)

 Benchmark                       (size)  Mode Cnt         Score          Error Units  CountBenchmark.listSize 1 thrpt 5 966658591.905 ± 175787129.100 ops/s  CountBenchmark.listSize 1000 thrpt 5 862173760.015 ± 293958267.033 ops/s  CountBenchmark.listSize 1000000 thrpt 5 879607621.737 ± 107212069.065 ops/s  CountBenchmark.listStreamCount 1 thrpt 5 39570790.720 ± 3590270.059 ops/s  CountBenchmark.listStreamCount 1000 thrpt 5 30383397.354 ± 10194137.917 ops/s  CountBenchmark.listStreamCount 1000000 thrpt 5 398.959 ± 170.737 ops/s 

JDK 11

 Benchmark                                 (size)  Mode Cnt         Score          Error Units  CountBenchmark.listSize 1 thrpt 5 898916944.365 ± 235047181.830 ops/s  CountBenchmark.listSize 1000 thrpt 5 865080967.750 ± 203793349.257 ops/s  CountBenchmark.listSize 1000000 thrpt 5 935820818.641 ± 95756219.869 ops/s  CountBenchmark.listStreamCount 1 thrpt 5 95660206.302 ± 27337762.894 ops/s  CountBenchmark.listStreamCount 1000 thrpt 5 78899026.467 ± 26299885.209 ops/s  CountBenchmark.listStreamCount 1000000 thrpt 5 83223688.534 ± 16119403.504 ops/s 

可以看出,在Java 11中, list.stream().count()操作现在是
O(1)而不是O(N)

Brian Goetz 指出 ,一些在Java 8下使用Stream::peek方法调用的开发人员发现,如果Stream::count终端操作在Java 9及更高版本下运行,则不再调用这些方法。 这给JDK开发人员带来了一些负面反馈。 就我个人而言,我认为这是JDK开发人员的正确决定,相反,这为
Stream::peek用户使他们的代码正确。

更复杂的流管道

在本章中,我们将介绍更复杂的流管道。

JDK 11

Tagir Valeev 得出结论 ,对于List::stream ,类似stream().skip(1).count()类的管道不是O(1)

通过运行以下基准可以观察到这一点:

 @Benchmark  public long listStreamSkipCount() { return list.stream().skip( 1 ).count();  } 
 CountBenchmark.listStreamCount 1 thrpt 5 105546649.075 ± 10529832.319 ops/s  CountBenchmark.listStreamCount 1000 thrpt 5 81370237.291 ± 15566491.838 ops/s  CountBenchmark.listStreamCount 1000000 thrpt 5 75929699.395 ± 14784433.428 ops/s  CountBenchmark.listStreamSkipCount 1 thrpt 5 35809816.451 ± 12055461.025 ops/s  CountBenchmark.listStreamSkipCount 1000 thrpt 5 3098848.946 ± 339437.339 ops/s  CountBenchmark.listStreamSkipCount 1000000 thrpt 5 3646.513 ± 254.442 ops/s 

因此, list.stream().skip(1).count()仍为O(N)。

加速

一些流实现实际上知道它们的源,并且可以采用适当的快捷方式并将流操作合并到流源本身中。 这可以大大提高性能,尤其是对于具有更复杂的流管道(例如stream().skip(1).count()大型流stream().skip(1).count()

Speedment ORM工具允许将数据库视为Stream对象,并且这些流可以优化许多流操作,例如
Stream::countStream::skipStream::limit操作,如下面的基准所示。 我已使用开源Sakila示例数据库作为数据输入。 Sakila数据库包含有关租赁电影,艺术家等的全部信息。

 @Benchmark  public long rentalsSkipCount() { return rentals.stream().skip( 1 ).count();  }  @Benchmark  public long filmsSkipCount() { return films.stream().skip( 1 ).count();  } 

运行时,将产生以下输出:

 SpeedmentCountBenchmark.filmsSkipCount       N/A thrpt 5 68052838.621 ± 739171.008 ops/s  SpeedmentCountBenchmark.rentalsSkipCount     N/A thrpt 5 68224985.736 ± 2683811.510 ops/s 

“租赁”表包含10,000行,而“电影”表仅包含1,000行。 但是,它们的stream().skip(1).count()操作几乎同时完成。 即使一个表包含一万亿行,它仍然会在相同的经过时间内对元素进行计数。 因此, stream().skip(1).count()实现的复杂度为O(1)而不是O(N)

注意:上面的基准测试是通过“ DataStore” JVM中的内存加速来运行的。 如果直接对数据库没有加速运行,则响应时间将取决于基础数据库执行嵌套“SELECT count(*) …”语句的能力。

摘要

在Java 9中Stream::count显着改善。

有些流实现(例如Speedment O(1)即使在更复杂的流管道(例如stream().skip(...).count()甚至stream.filter(...).skip(...).count() stream().skip(...).count() ,也可以在O(1)时间内计算Stream::count stream().skip(...).count() stream.filter(...).skip(...).count()

资源资源

Speedment Stream ORM初始化程序: https ://www.speedment.com/initializer/

Sakila: https ://dev.mysql.com/doc/index-other.html或https://hub.docker.com/r/restsql/mysql-sakila

翻译自: https://www.javacodegeeks.com/2019/04/java-stream-part-2-count-always-count.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/343554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤教育】国家开放大学2018年春季 0062-21T港台文学专题讲座 参考试题

试卷编号&#xff1a;0062 座位号 2017——2018学年度第二学期期末考试 中国当代文学专题 试题&#xff08;开&#xff09; 2018年7月 什么叫“伤痕文学”&#xff1f;什么叫“反思文学”&#xff1f;什么叫“改革文学”&#xff1f;各说出两位作家及作品。1&#xff0e;说明…

mysql 横向分表合并_MySQL横向扩展-分库分表解决方案总结

从业务场景看分库分表互联网行业中&#xff0c;业务场景通常写少读多的情况居多&#xff0c;在MySQL的使用前期&#xff0c;读性能大多可以通过SQL优化来解决&#xff0c;但随着业务的持续发展&#xff0c;单纯依靠SQL的查询优化会越来越难以达到业务服务要求。因此&#xff0c…

【渝粤教育】国家开放大学2018年春季 0089-22DInternet和Intranet应用 参考试题

编号&#xff1a;0089 17-18学年第1学期期末考试 Internet和Intranet应用 试题答案 一、填空题&#xff1a;&#xff08;每空4分&#xff0c;共40分&#xff09; 1&#xff0e;网络接口层  网际网层  传输层  应用层 2&#xff0e;路由器(或网关)  目的主机 3&#xff…

家用、商用、工业交换机的用途与区别

以太网交换机一般分为&#xff1a;商用(以太网)交换机、工业(以太网)交换机、家用(以太网)交换机。那么&#xff0c;家用交换机&#xff0c;商业交换机&#xff0c;工业交换机之间有什么区别呢&#xff1f;接下来我们就跟随飞畅科技的小编一起来详细了解下吧&#xff01; 商用…

【渝粤教育】国家开放大学2018年春季 0105-22T酒店营销实务 参考试题

科目编号&#xff1a;0105 座位号 2017年度第二学期期末考试 酒店营销实务 试题 2018年7月 一、名词解释&#xff1a;&#xff08;每题5分&#xff0c;共20分&#xff09; 酒店广告&#xff1a; 酒店市场细分&#xff1a; 3&#xff0e;市场调查&#xff1a; 目标市场&…

【渝粤教育】国家开放大学2018年春季 0176-22T电机学(一) 参考试题

编号&#xff1a; 0176 2017-2018年度第二学期期末考试 电机学&#xff08;1&#xff09; 试 题 2018年 7 月 一、填空题&#xff08;每空4分&#xff0c;共40分&#xff09; 1&#xff0e;一台变压器&#xff0c;加额定电压时&#xff0c;主磁通为Φ&#xff0c;空载电流为I…

python中dump用法_python中json庫中的load、loads、dump、dumps的區別與用法

一、json.dumps(i)&#xff1a;json中的dumps方法是用來將特定格式的數據進行字符串化的操作&#xff0c;比如列表字典都可以進行字符串化操作然后寫入json的file&#xff1b;而且如果是要寫入json文件就必須要進行dumps操作&#xff1b;二、json.dump():和dumps差一個s&#x…

监控POE供电交换机最大传输距离有多远?

经常有朋友问到关于POE供电技术的问题&#xff0c;比如说POE供电最大传输距离是多远?其实&#xff0c;PoE最大传输距离的问题&#xff0c;先要弄清楚决定最大距离的关键因素是什么。事实上&#xff0c;用标准以太网线缆(双绞线)传输直流电是可以传输很远的&#xff0c;这个距离…

【渝粤教育】国家开放大学2018年春季 0233-21T学前儿童语言教育 参考试题

试卷编号&#xff1a;0233 2017——2018学年度第二学期期末考试 学前儿童语言教育 2018年7月 1.前语言阶段&#xff0c;儿童发展了三方面能力&#xff0c;即前语言 、前语言 和前语言 。 2. 和 &#xff0c;这是儿童学话中的关键的两步&#xff0c;因为语言基本的奥秘已开始渗…

aop 代码_项目学生:使用AOP简化代码

aop 代码这是Project Student的一部分。 许多人坚信方法应适合您的编辑器窗口&#xff08;例如20行&#xff09;&#xff0c;而有些人认为方法应小于此范围。 这个想法是一种方法应该做一件事&#xff0c;而只能做一件事。 如果它做的还不止于此&#xff0c;则应将其分解为多种…

【渝粤教育】国家开放大学2018年春季 0269-21T文学概论 参考试题

试卷代号&#xff1a;0269 2017-2018年度第二学期考试 文学概论试题 2018年7月 一、选择题&#xff08;请在下面的答题框内写上正确答案的序号&#xff09;&#xff08;每小题3分&#xff0c;共30分&#xff09; 1. 在研究长篇小说的文体语言的时候&#xff0c;俄国学者____…

HDMI视频光端机常见故障问题及解决方法

HDMI光端机就是光信号传输的终端设备&#xff0c;在广泛领域应用中&#xff0c;往往需要把HDMI信号源输送远处进行处理。最为突出的问题有&#xff1a;远处接收到的信号出现偏色、模糊&#xff0c;信号产生重影和拖尾及网纹干扰。那么&#xff0c;我们在使用HDMI视频光端机时常…

【渝粤教育】国家开放大学2018年春季 0299-22T中国古代文学(1) 参考试题

试卷编号&#xff1a;0299 座位号 2017—2018学年度第2学期期末考试 中国古代文学&#xff08;1&#xff09;试题(闭卷) 2018年5月 1.枚乘的《 》是汉赋发展史上一篇带有转折性的作品。 2. 汉代两位最杰出的史学家是 、 。他们的史学著作里的许多人物传记是传记散文的杰作。 …

将Spring Boot应用程序部署到Tomcat中

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 部署应用程序很困难。 通常&#xff0c;您需要控制台访问服务器&#xff0c;从服务器…

【渝粤教育】国家开放大学2018年春季 0463-22T英语语音 参考试题

科目编号&#xff1a;0463 座位号&#xff1a; 2017─2018学年度第二学期期末考试 英语语音笔试题 (开卷) 2018年7月 根据读音规则为下列单词注音 &#xff08;10分&#xff09; Saturday 2. notify demand 4. country 5. answer 6. police pronounce 8. magazine popular…

python读取excel写入mysql pandas_python pandas 读取文件 写入文件excel

读取数据import pandas as pdimport collectionsdef readLocationCodeForExcel():read_file r"test.xlsx"sheet_names {"库位码","地堆码"}sheet_data pd.ExcelFile(read_file) #读取sheet数据#sheet列表read_sheet_data sheet_data.sheet_n…

【渝粤教育】国家开放大学2018年春季 0553-21T色彩 参考试题

编号&#xff1a;0553 座位号&#xff1a; 2017&#xff5e;2018学年度第二学期期末考试 色彩试题 2018年7月 色彩写生画&#xff08;100分&#xff09; 题目&#xff1a;水粉色彩静物写生。 静物&#xff1a;由10件不同造型、色调、质感的静物组合并配置衬布 红色花瓶、鲜花一…

HD-SDI光端机是什么?其性能特点和技术参数有哪些?

HD-SDI光端机是将SDI信号与光信号互相转换的设备。SDI光端机的原理是发送端将SDI信号通过激光器调制后变为光信号,接收端将激光二极管收到的数据再编码为SDI信号。那么&#xff0c;HD-SDI光端机是什么呢&#xff1f;其性能特点和技术参数有哪些呢&#xff1f;接下来我们就跟随飞…

【渝粤教育】国家开放大学2018年春季 0609-21T中级财务会计(1) 参考试题

科目编号&#xff1a;0609 座位号 2017-2018学年度第二学期期末考试 中级财务会计&#xff08;1&#xff09; 试题 2018年 7 月 一、单选题&#xff08;本大题共10小题&#xff0c;每小题3分&#xff0c;共计30分&#xff09; &#xff08;★请考生务必将答案填入到下面对应序…

flask查询mysql数据展示_flask下直接展示mysql数据库 字段

from flask importFlask,request,render_templatefrom flask_sqlalchemy importSQLAlchemyapp Flask(__name__)app.config[SQLALCHEMY_DATABASE_URI] sqlite:///test.db #这里用这个是不行的 注意修改为&#xff4d;&#xff59;&#xff53;&#xff51;&#xff4c; 才可以…