在Java 8中,你只要用以下寫法,很容易就可以讓你的工作並行化:
list.stream().parallel() .. list.parallelStream() ..但這個item要強調的是: 千萬別亂用!! (以下內容我結合Java 8 Lambdas技術手冊做補充)
能獲得較佳效能的結構有ArrayList、HashMap、HashSet、ConcurrentHashMap、arrays、int ranges與long ranges。這是由於它們的結構能夠容易被切割。書中還有提到Prefer SplittableRandom than ThreadLocalRandom,但這部分我沒使用過,無法做深入說明。
這通常是無法容易被切割的結構,像是LinkedList,我就有遇過同事使用LinkedList做parallel();再來就是使用Stream.iterate與BufferedReader.lines所產生的stream,因為初始長度未知。
另外容易被忽略的就是boxing和un-boxing轉換的效能問題,如果可以要盡量減少auto-boxing的操作,如此link所示。
能獲得較佳效能的terminal operations包含reduce、min、max、count與sum;short-circuiting operations包含anyMatch、allMatch與noneMatch。(short-circuiting operations代表著滿足部分條件就可以停止繼續做下去,中文為短路操作,詳細範例可以參考link)
除此之外,還有一個重點就是操作是否有狀態,有狀態就會有維持狀的成本與限制;無狀態操作包含map、filter與flatMap。
有狀態操作包含了sorted、distinct與limit。其中limit在effective java中是特別被列為不適用,這是由於預設的並行化流程並無法精準的知道該怎麼正確處理limit的邏輯。
collect也不適合用在parallel的情況中,因為組合集合開銷非常大;我們大都使用parallel在物件的轉換上,此時資料量會是決定你效能的一個因素。
根據Java 8 Doc,預設的parallelism為處理器核心處量。假如這個值設太大,會導致大量的context switch。