10
關於Java8 Stream 的使用時機 (/z/programming)

其實我是看了這篇文章 Parallel Streams and Spliterators1 才知道原來Internal iteration 會有small performance penalty. 但是看了數據感覺還差蠻多的...@@

  • External, sequential (for-loop): 8.5 seconds
  • External, parallel (ForkJoin): 2.5 second
  • Internal, sequential (sequential stream): 21 seconds
  • Internal, parallel (parallel stream): 6 seconds

所以需要針對效能考慮嗎? 還是反正就trade-off 用stream 寫法可以少寫一些code也少一些bug (這我也懷疑...XD)

howie 積分 0 編輯於
popcorny 積分 0

可以用parallel當然用parallel,這樣才可以利用到Multicore的好處。

IngramChen 積分 1

不,完全要 benchmark 過才可以用,真的能用的地方不多。

popcorny 積分 5 編輯於

哈哈。的確我寫的太武斷。我當初腦袋中所想的是,問題"可以適合用parallel"就用parallel,但不能說所有問題都適合平行。直接這樣寫確實不太恰當。

那什麼叫做適合parallel?

  1. 你跑的job要夠長!! 如果跑的東西都是瞬殺,那就直接用sequential跑就好了。
  2. 可以Split。可能input本身就可以split那最好,如果你中間的某一段開始一分多,例如collectors.groupingBy,那就可以讓後續的aggregation平行做。
  3. 問題本身適不適合平行。如果你的filter, mapper會有side effect,那就不能平行。reducer有沒有交換律結合律的特性,沒有也不適合平行。
  4. 輸出需不需要符合原有順序。如果你只是想要stream.map().foreach()。那是不是還想要某個順序執行。

以上幾點都非常重要,很多時候你的東西在沒有parallel是對的,但是丟到平行就錯了。當然如果以上都符合,那用parallel的好處就是善用你的每個CPU Core。看到CPU榨乾才會有滿滿的效能啊!!

另外不一定說要用Stream的平行,也不一定直接用ForkJoinExecutor。用CompletableFuture + Sequencial Stream也可以輕鬆善用CPU Multicore的好處。

howie 積分 0

恩我看到文章是很多地方雖然可以parallel但是會被content switch...等問提把好處都消耗光~所以真的很難說...

caterpillar 積分 3

執行資料平行處理的效能考量1 有談一些,也可以参考《Java 8 Lambdas》那本書中對效能的討論。

kaif 積分 0

Java 8 Lambdas有提到,如果程式是多個loop去串接的,此時用Internal iteration可以惰性求值,因此性能有機會優於external loop。書上沒有提供測試數據,僅是定性的敘述。

koji 積分 2

他跑的次數太大了,正常來說整個功能中這些 stream 的動作應該不會是最大的比重。如果是我,我應該會先把其他效能瓶頸都處理完後才會去擔心這部分。

popcorny 積分 1

同意。他的例子是極端簡單的iteration,且跑10M次,才會覺得改善顯著。但一般情況可能I/O, decompress, deserialize, string processing這些都完全大於stream overhead