第四章 並行化Stream流
關注公眾號(CoderBuff)回復“stream”獲取《Java8 Stream編碼實戰》PDF完整版。
《Java8 Stream編碼實戰》的代碼全部在https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/stream-coding,一定要配合源碼閱讀,並且不斷加以實踐,才能更好的掌握Stream。
在現實當中,並行化流開始並沒有引起我的注意,直到我發現了它的應用場景后才發現,並行化流在提高性能以及編碼難易程度上,代碼bug上似乎要更勝一籌。
“第三章 Stream流”一直介紹的是串行化的流,串行化的流如果你有心可以和for循環對比,會發現串行化的流在性能上是比for循環要差的。這也是部分人“鄙視”Stream流的一點。
4.1 並行與並發
並行,指的是在同一時刻多個任務同時執行。
並發,指的是在同一時間段多個任務交替執行。
當然,並行的執行速度更快,但並行也依賴硬件設置,因為它依賴硬件CPU是多核的場景。並發則不受限制。
parallelStream
想要把串行流轉換為並行流很簡單,只需要將stream
修改為parallelStream
,其它操作不變。
public void parallel(List<Student> students) {
students.parallelStream()
.map(Student::getStudentNumber)
.collect(Collectors.toList());
}
Stream流的並行化操作,是一種數據並行化,流本身就擅長對數據進行運算。
當然並不是將代碼里所有的串行流改為並行流就萬事大吉性能翻倍了,數據少了不行,CPU核數不夠也不行。所以要想真正能提高性能,還要針對實際請做測試才能得出結論。
我們分別舉幾個數據量不同的例子,來說明for循環、串行化Stream流、並行化Stream流的性能在我本機的性能。
我測試了9個學生、90個學生、9000個學生、90000個學生后,三者的性能表現如下圖所示:
com.coderbuff.chapter4_parallelstream.PerformanceTests
操作 | 9個學生 | 90個學生 | 900個學生 | 9000個學生 | 90000個學生 | 900000個學生 |
---|---|---|---|---|---|---|
for循環 | 0ms | 0ms | 2ms | 8ms | 41ms | 343ms |
串行化Stream | 61ms | 1ms | 2ms | 4ms | 27ms | 789ms |
並行化Stream | 4ms | 0ms | 4ms | 3ms | 88ms | 358ms |
從曲線圖可以看出90000個學生以前3者的性能都是幾毫秒,並沒有太大區別,從90000個學生過后,串行化流性能主鍵走弱,並行化流的性能開始逐漸趕上for循環,但注意這並不意味着從900000個數據后並行化的數據就一定會超越for循環。由於后兩組測試數據比較大,我們去掉90000和900000這兩組數據的性能曲線圖。
從這張圖可以看到,串行化流在數據量很小的情況下,性能最差。而並行化流則處於波動的狀態。
所以單單從數據量上可以看出:
for循環的性能隨着數據量的增加性能也越來越差。
串行化流則在數據量小的情況下性能差,數據量中、大的時候性能略高於for循環,但當數據量特別大時,性能也變得越差。
並行化流受CPU核數的影響,在本機2核下,在數據量小的情況下性能略高於串行化流,略低於for循環,在數據量中的情況下差不多,在數據量比較大時性能最差,但當數據量特別大時,性能也變得更好。
如果想要使用parallelStream
想提高性能,一定要根據實際情況做好測試,因為並行化的流性能不一定比串行化流性能高。
關注公眾號(CoderBuff)回復“stream”搶先獲取PDF完整版。
近期教程:
