高效使用並行流

高效使用並行流

        一般而言,想給出任何關於什麼時候該用並行流的定量建議都是不可能也毫無意義的,因爲任何類似於“僅當至少有一千個(或一百萬個或隨便什麼數字)元素的時候才用並行流”的建議對於某臺特定機器上的某個特定操作可能是對的,但在略有差異的另一種情況下可能就是大錯特錯。儘管如此,我們至少可以提出一些定性意見,幫你決定某個特定情況下是否有必要使用並行流。

        如果有疑問,測量。把順序流轉成並行流輕而易舉,但卻不一定是好事。我們在本節中已經指出,並行流並不總是比順序流快。此外,並行流有時候會和你的直覺不一致,所以在考慮選擇順序流還是並行流時,第一個也是最重要的建議就是用適當的基準來檢查其性能。

        留意裝箱。自動裝箱和拆箱操作會大大降低性能。 Java8中有原始類型流( Instream、Longstream、 Doublestream)來避免這種操作,但凡有可能都應該用這些流。

        有些操作本身在並行流上的性能就比順序流差。特別是1imit和 findfirst等依賴於元素順序的操作,它們在並行流上執行的代價非常大。例如, findany會比 finai rst性能好,因爲它不一定要按順序來執行。你總是可以調用 unordered方法來把有序流變成無序流。那麼,如果你需要流中的n個元素而不是專門要前個的話,對無序並行流調用mit可能會比單個有序流(比如數據源是一個List)更高效。

        還要考慮流的操作流水線的總計算成本。設N是要處理的元素的總數,是一個元素通過流水線的大致處理成本,則NQ就是這個對成本的一個粗略的定性估計。值較高就意味着使用並行流時性能好的可能性比較大。

       對於較小的數據量,選擇並行流幾乎從來都不是一個好的決定。並行處理少數幾個元素的好處還抵不上並行化造成的額外開銷。         要考慮流背後的數據結構是否易於分解。例如, Arraylist的拆分效率比 Linkedlist高得多,因爲前者用不着遍歷就可以平均拆分,而後者則必須遍歷。另外,用 range工廠方法創建的原始類型流也可以快速分解。最後,你將在73節中學到,你可以自己實現sp1 iterator來完全掌控分解過程 

        流自身的特點,以及流水線中的中間操作修改流的方式,都可能會改變分解過程的性能例如,一個SエZED流可以分成大小相等的兩部分,這樣每個部分都可以比較高效地並行處理,但篩選操作可能丟棄的元素個數卻無法預測,導致流本身的大小未知

       還要考慮終端操作中合併步驟的代價是大是小(例如co1 l ector中的 combiner方法)。如果這一步代價很大,那麼組合每個子流產生的部分結果所付出的代價就可能會超出通過並行流得到的性能提升。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章