大家都知道 Stream 分为顺序流和并行流:
它们最大的区别就是 parallelStream 支持并行化处理,所以效率较 stream(顺序流)肯定是要更快的。这篇不会介绍 Stream 基础,Stream 系列我之前写过一个专题了,不懂的关注公众号Java技术栈,然后在公众号 Java 教程菜单中阅读。
然而你确定 parallelStream 一定要更快吗?
栈长写了一段排序的示例,分别用 stream 和 parallelStream,对 100 ~ 10000000 条数据的集合进行排序,来看下执行效率究竟如何!
顺序流排序:
/**
* 顺序流排序
* @author: 栈长
* @from: 公众号Java技术栈
*/
private static void streamSort() {
long start = System.currentTimeMillis();
List<SortTest.User> list = new ArrayList<>(LIST);
list.stream().sorted(SortTest.User::compareAge).collect(Collectors.toList());
System.out.println("\nList size: " + list.size() + " Stream.sorted: " + (System.currentTimeMillis() - start));
}
并行流排序:
/**
* 并行流排序
* @author: 栈长
* @from: 公众号Java技术栈
*/
private static void parallelStreamSort() {
long start = System.currentTimeMillis();
List<SortTest.User> list = new ArrayList<>(LIST);
list.parallelStream().sorted(SortTest.User::compareAge).collect(Collectors.toList());
System.out.println("List size: " + list.size() + " ParallelStream.sorted: " + (System.currentTimeMillis() - start));
}
本文所有完整示例源代码已经上传:
执行结果如下:
List size: 10000000 Stream.sorted: 202
List size: 10000000 ParallelStream.sorted: 402List size: 1000000 Stream.sorted: 53
List size: 1000000 ParallelStream.sorted: 15List size: 100000 Stream.sorted: 1
List size: 100000 ParallelStream.sorted: 2List size: 10000 Stream.sorted: 0
List size: 10000 ParallelStream.sorted: 1List size: 1000 Stream.sorted: 0
List size: 1000 ParallelStream.sorted: 1List size: 100 Stream.sorted: 0
List size: 100 ParallelStream.sorted: 0
在 100000 以下是没什么区别的;
在 1000000 左右 ParallelStream 虽然领先 Stream,但也不是绝对每次都领先,经过不断测试,这个数据量区间的测试两者会互相领先;
在 10000000 左右就很稳定了,ParallelStream 几乎比 Stream 慢了 2 倍!
现在你可能会有疑问了,为什么会这样?
栈长起初也有疑问,并行流(ParallelStream)怎么会比顺序流(Stream)还要慢。。
其实我后面想想也就明白了,并行流(ParallelStream)的背后其实是 Java7 开始支持的 Fork/Join,即把一个大任务拆分成 N 个小任务,然后最终合并各个子任务的结果,所以对于子任务线程的拆分、创建、结果合并等操作都需要不少的开销,特别是线程的创建。
所以这种不耗时的简单排序操作事实上是不适用于并行流(ParallelStream)的,它所带来的线程创建的损耗可能还会比顺序流(Stream)还要更慢。
最新 Java 8+ 面试题也都整理好了,点击Java面试库小程序在线刷题。
既然使用 Fork/Join 是会有损耗的,那对于单条数据的处理的时间最好是理论上要超过用并行流(ParallelStream)本身的损耗,这种情况下就比较合适。
也就是说,如果对于流中的每条数据的处理比较费时间,并且没有顺序要求,这种场景下用并行流(ParallelStream)会更快,更合适。
来看下面这个示例:
顺序流数据处理:
/**
* 顺序流数据处理
* @author: 栈长
* @from: 公众号Java技术栈
*/
private static void streamProcess() {
long start = System.currentTimeMillis();
List<SortTest.User> list = new ArrayList<>(LIST);
list.stream().map(StreamSpeedTest::process).collect(Collectors.toList());
System.out.println("\nList size: " + list.size() + " Stream process: " + (System.currentTimeMillis() - start));
}
并行流数据处理:
/**
* 并行流数据处理
* @author: 栈长
* @from: 公众号Java技术栈
*/
private static void parallelStreamProcess() {
long start = System.currentTimeMillis();
List<SortTest.User> list = new ArrayList<>(LIST);
list.parallelStream().map(StreamSpeedTest::process).collect(Collectors.toList());
System.out.println("List size: " + list.size() + " ParallelStream process: " + (System.currentTimeMillis() - start));
}
数据处理:
/**
* 数据处理
* @author: 栈长
* @from: 公众号Java技术栈
*/
private static SortTest.User process(SortTest.User user) {
try {
user.setName(user.getName() + ": process");
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return user;
}
注意: 这里加了个休眠 5 毫秒,为了体现真实的处理数据耗时。
本文所有完整示例源代码已经上传:
并行流排序:
List size: 1000 Stream process: 5750
List size: 1000 ParallelStream process: 745List size: 100 Stream process: 566
List size: 100 ParallelStream process: 77
结果很明显了,不管测试多少次,并行流(ParallelStream)的处理速度都要比顺序流(Stream)要快几倍!!我这里只测试了 100 和 1000 条数据,因为 10000 条以上的数据用顺序流(Stream)可能要等非常久。
而且我程序中的处理逻辑只休眠了 5 毫秒,如果实际处理单条数据的耗时要比这个更长,那并行流(ParallelStream)的处理效率还会更明显。
稍微总结下:
所以,你学废了吗?赶紧发给身边的同事看看吧,别再乱用 parallelStream 了!用的不好,存在线程安全问题不说,效率上可能还会适得其反。
大家如果对 Java 8 新增的知识点(Lambda、Stream、函数式接口等)还不会用的可以关注公众号:Java技术栈,在 Java 教程菜单中阅读,Java 8+ 系列教程我都写了一堆了。
本文所有完整示例源代码已经上传:
欢迎 Star 学习,后面 Java 示例都会在这上面提供!
好了,今天的分享就到这里了,后面栈长会分享更多好玩的 Java 技术和最新的技术资讯,关注公众号Java技术栈第一时间推送,我也将主流 Java 面试题和参考答案都整理好了,在公众号后台回复关键字 "面试" 进行刷题。
最后,觉得我的文章对你用收获的话,动动小手,给个在看、转发,原创不易,栈长需要你的鼓励。
版权声明: 本文系公众号 "Java技术栈" 原创,转载、引用本文内容请注明出处,抄袭、洗稿一律投诉侵权,后果自负,并保留追究其法律责任的权利。
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2022最新版)
4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!
觉得不错,别忘了随手点赞+转发哦!
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。在我在网上找到的每个基准测试中,Ruby似乎都很慢,比Java慢得多。Ruby的人只是说这无关紧要。您能举个例子说明RubyonRails(以及Ruby本身)的速度真的无关紧要吗?
我有这段代码:date_counter=Time.mktime(2011,01,01,00,00,00,"+05:00")@weeks=Array.new(date_counter..Time.now).step(1.week)do|week|logger.debug"WEEK:"+week.inspect@weeks从技术上讲,代码有效,输出:SatJan0100:00:00-05002011SatJan0800:00:00-05002011SatJan1500:00:00-05002011etc.但是执行时间完全是垃圾!每周计算大约需要四秒钟。我在这段代码中是否遗漏了一些奇怪的低效
我想知道NokogiriXPath或CSS解析是否可以更快地处理HTML文件。速度有何不同? 最佳答案 Nokogiri没有XPath或CSS解析。它将XML/HTML解析为单个DOM,然后您可以使用CSS或XPath语法进行查询。CSS选择器在要求libxml2执行查询之前在内部转换为XPath。因此(对于完全相同的选择器)XPath版本会快一点点,因为CSS不需要先转换成XPath。但是,您的问题没有通用答案;这取决于您选择的是什么,以及您的XPath是什么样的。很有可能,您不会编写与Nokogiri创建的相同的XPath。例如
我有一个Rails应用程序,在开发模式下运行(使用sqlite数据库)。该应用程序的目的是允许用户通过Java客户端上传文件。如果用户要上传一个文件夹,会递归上传里面的所有文件。如果用户要上传文件,文件将正常上传。这是我收到的错误:IOErrorinUploadedFilesController#newclosedstream这是应用程序跟踪:/usr/lib/ruby/1.8/tempfile.rb:167:in`close'/usr/lib/ruby/1.8/tempfile.rb:167:in`callback'/var/lib/gems/1.8/gems/activesuppo
过程和lambdadiffer关于方法范围和return关键字的效果。我对它们之间的性能差异很感兴趣。我写了一个测试,如下所示:deftime(&block)start=Time.nowblock.callp"thattook#{Time.now-start}"enddeftest(proc)time{(0..10000000).each{|n|proc.call(n)}}enddeftest_block(&block)time{(0..10000000).each{|n|block.call(n)}}enddefmethod_testtime{(1..10000000).each{|
Two-StreamConvolutionalNetworksforActionRecognitioninVideos双流网络论文精读论文:Two-StreamConvolutionalNetworksforActionRecognitioninVideos链接:https://arxiv.org/abs/1406.2199本文是深度学习应用在视频分类领域的开山之作,双流网络的意思就是使用了两个卷积神经网络,一个是SpatialstreamConvNet,一个是TemporalstreamConvNet。此前的研究者在将卷积神经网络直接应用在视频分类中时,效果并不好。作者认为可能是因为卷积神经
我正在使用RubyonRails3.2.2、FactoryGirl3.1.0、FactoryGirlRails3.1.0、Rspec2.9.0和RspecRails2.9.0。为了测试我的应用程序,我必须在数据库中创建大量记录(大约5000条),但是该操作非常慢(创建记录需要10多分钟)。我这样进行:before(:each)do5000.timesdoFactoryGirl.create(:article,)endend如何改进我的规范代码以加快速度?注意:可能速度较慢是由在每个文章创建过程前后运行的(5)个文章回调引起的,但我可以跳过这些(因为我唯一需要测试的是文章和不是关联的模型
从来源(database_cleaner,active_record)来看,它们应该同样快。但是有人声称使用database_cleaner的事务策略会降低Controller和模型规范的速度(forexample)。我手头没有用于基准测试的大型测试套件。任何人有任何见解或比较两者? 最佳答案 我花了一点时间在广泛使用ActiveRecord固定装置的中型代码库上比较两者。当我将其切换为使用DatabaseCleaner而不是use_transactional_fixtures时,模型规范开始花费大约两倍的时间。在进行了与您相同的比
Ai-Bot基于流行的Node.js和JavaScript语言的一款新自动化框架,支持Windows和Android自动化。1、Windowsxpath元素定位算法支持支持Windows应用、.NET、WPF、Qt、Java和Electron客户端程序和ie、edgechrome浏览器2、Android支持原生APP和H5界面,元素定位速度是appium十倍,无线远程自动化操作多台安卓设备3、基于opencv图色算法,支持找图和多点找色,1080*2340全分辨率找图50MS以内4、内置免费OCR人工智能技术,无限制获取图片文字和找字功能。5、框架协议开源,除官方node.jsSDK外,用户可