最近在使用parallelStream的时候发现一个并不能提升系效率的情况,代码如下
@Test
public void testStream() {
List<String> stringList = new ArrayList<>();
int count = 1000000;
for (int i = 0; i < count; i++) {
stringList.add(Integer.toString(i));
}
long startTime = System.currentTimeMillis();
ConcurrentMap<String, String> collect = stringList
.stream().collect(Collectors.toConcurrentMap((a) -> a, this::addString));
long costTime = System.currentTimeMillis() - startTime;
System.out.println("------------------" + costTime);
for (Map.Entry<String, String> stringStringEntry : collect.entrySet()) {
Assert.assertEquals(stringStringEntry.getValue(), stringStringEntry.getKey() + "1");
}
}
private String addString(String i) {
return i + "1";
}
此时使用stream的耗时大概在:456ms左右。
但是当改成并行流parallelStream的时候,代码如下,发现耗时却增加了,大概在661ms左右
@Test
public void testStream() {
List<String> stringList = new ArrayList<>();
int count = 1000000;
for (int i = 0; i < count; i++) {
stringList.add(Integer.toString(i));
}
long startTime = System.currentTimeMillis();
ConcurrentMap<String, String> collect = stringList
.stream().collect(Collectors.toConcurrentMap((a) -> a, this::addString));
long costTime = System.currentTimeMillis() - startTime;
System.out.println("------------------" + costTime);
for (Map.Entry<String, String> stringStringEntry : collect.entrySet()) {
Assert.assertEquals(stringStringEntry.getValue(), stringStringEntry.getKey() + "1");
}
}
private String addString(String i) {
return i + "1";
}
现在就会疑问了,parallelStream不应比Stream快吗,这是怎么回事?
我起初也有疑问,并行流(ParallelStream)怎么会比顺序流(Stream)还要慢。。
其实我后面想想也就明白了,并行流(ParallelStream)的背后其实是 Java7 开始支持的Fork/Join,即把一个大任务拆分成 N 个小任务,然后最终合并各个子任务的结果,所以对于子任务线程的拆分、创建、结果合并等操作都需要不少的开销,特别是线程的创建。
所以这种不耗时的简单排序操作事实上是不适用于并行流(ParallelStream)的,它所带来的线程创建的损耗可能还会比顺序流(Stream)还要更慢。
那么问题来了,什么时候用 ParallelStream?
既然使用 Fork/Join 是会有损耗的,那对于单条数据的处理的时间最好是理论上要超过用并行流(ParallelStream)本身的损耗,这种情况下就比较合适。
也就是说,如果对于流中的每条数据的处理比较费时间,并且没有顺序要求,这种场景下用并行流(ParallelStream)会更快,更合适。
总结:
- stream: 适用于避免线程安全问题、要求顺序执行、数据处理简单不耗时的任务;
- parallelStream: 适用于不存在线程安全问题、不需要顺序性执行、数据处理比较耗时的任务;
参考文章:https://blog.youkuaiyun.com/m0_73311735/article/details/126661732