本文主要是介绍Java中迭代、流(stream)、并行流(parallelStream)效率简单测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在查阅示例代码时,看到Java流库,回故下其简洁的语法要比循环迭代优美、易读很多。
1. 测试
一时好奇想简单测试下迭代、流、并行流的运行效率。
测试环境:
计算机:DELL Inspiron 7572
处理器:Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz 1.99GHz
内存:16GB
系统类型:Window10 64位
测试代码如下:
package study;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;public class CountLongWords {public static void main(String[] args) throws IOException {//for 效率测试long from = System.currentTimeMillis();String contents = new String(Files.readAllBytes(Paths.get("test.txt")), StandardCharsets.UTF_8);List<String> words = Arrays.asList(contents.split("\\PL+"));long count = 0;for (String w : words){if (w.length() > 5){count++;}}long to = System.currentTimeMillis();System.out.println("long word count : " + count);System.out.println("time1 : " + (to - from) + " ms");//stream 效率测试from = System.currentTimeMillis();String contents1 = new String(Files.readAllBytes(Paths.get("test1.txt")), StandardCharsets.UTF_8);List<String> words1 = Arrays.asList(contents.split("\\PL+"));count = words1.stream().filter(w -> w.length() > 5).count();to = System.currentTimeMillis();System.out.println("stream long word count : " + count);System.out.println("time2 : " + (to - from) + " ms");//parallelStream 效率测试from = System.currentTimeMillis();String contents2 = new String(Files.readAllBytes(Paths.get("test2.txt")), StandardCharsets.UTF_8);List<String> words2 = Arrays.asList(contents.split("\\PL+"));count = words2.parallelStream().filter(w -> w.length() > 5).count();to = System.currentTimeMillis();System.out.println("parallelStream long word count : " + count);System.out.println("time3 : " + (to - from) + " ms");}
}
其中:test.txt / test1.txt / test2.txt 是一样的英文内容文本,大小86.2MB。
2. 结果
测试1 | 测试2 | 测试3 | 测试4 | 测试5 | |
---|---|---|---|---|---|
迭代 | 2601 ms | 2633 ms | 2529 ms | 2602 ms | 2707 ms |
串行流 | 1931 ms | 1932 ms | 1923 ms | 1993 ms | 1939 ms |
并行流 | 1941 ms | 2134 ms | 2136 ms | 2256 ms | 2151 ms |
3. 总结
使用流(Stream)或并行流(parallelStream)效率比循环迭代的效率高
4. 拓展
按理说并行效率应该要比串行效率要高,但仔细看测试结果,可以注意到串行流的效率却比并行流的效率要高一些。
经查阅资料,使用并行流(parallelStream)时需要注意其特性,并不是所有情景下并行流(parallelStream)都可以发挥其优势。
从java8开始,并行编程变得很容易,通过并行流(parallelStream),可以很轻松的实现多线程并行处理。但是,这里面有个性能“陷阱”,如果不注意,使用并行流的效果反而更差,这个陷阱是什么呢?
这个陷阱就是,并行流默认都是用同一个默认的ForkJoinPool,这个ForkJoinPool的线程数和CPU的核心数相同。如果是计算密集型的操作,直接使用是没有问题的,因为这个ForkJoinPool会将所有的CPU打满,系统资源是没有浪费的,但是,如果其中还有IO操作或等待操作,这个默认的ForkJoinPool只能消耗一部分CPU,而另外的并行流因为获取不到该ForkJoinPool的使用权,性能将大大降低。可见,默认的ForkJoinPool必须只能处理计算密集型的任务。
那么,对应非计算密集型的任务,改怎么处理呢? 这就需要我们使用自己创建的ForkJoinPool来执行任务,下面给出实例代码:
ForkJoinPool forkJoinPool = new ForkJoinPool(8); forkJoinPool.submit(()->{tasks.parallelStream().forEach(t->{try {String gdsstatus=transactionService.GetTransInfo(url, t.getTask_id());checkStatus(t.getTask_id(),t.getTask_status(),gdsstatus);} catch (Exception e) {System.out.println("EXCEPTION OCCOR IN TASK:"+t.getTask_id());e.printStackTrace();}System.out.println("NO:"+count.getAndIncrement()+" is done");});});
参考:java并行流的性能“陷阱”
这篇关于Java中迭代、流(stream)、并行流(parallelStream)效率简单测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!