Re: Lambda 和Streams 可以慢5倍

看板java作者 (良葛格)時間8年前 (2015/12/03 17:03), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串3/3 (看更多)
※ 引述《eieio (好多目標)》之銘言: : 佳的寫法。慢五倍的關鍵並不是 stream,而是 boxing/unboxing : integers.stream().reduce(...) : integers.stream().mapToInt(Integer::intValue).reduce(...) : 上面兩個寫法,有先 mapToInt 就可以避免掉過多的 boxing/unboxing,速度 : 跟 for loop 差不多。 : 同樣的道理,下面這段 code 很不好: : String r = ""; : for (String s : strs) { : r = r + s; : } : 上面這段 code,每次 r = r + s 就會產生一個新的 String,效能會很低。 : 要避免產生無用的 String,要用 StringBuilder。 http://openhome.cc/Gossip/Programmer/Parallel.html Doug Lea在〈Stream Parallel Guidance〉文件中給了一些建議,對於 S.parallelStream().operation(F),如果N為S的元素數量,而Q為F處理每個元素的成本 ,可以大略使用F中的操作或行數來計算,如果N*Q至少超過10000,才有平行化的價值。 因此,如果操作簡單如x -> x + 1,那麼至少得有10000個以上的元素,才有平行化的價 值,相對地,如果每個元素涉及大量運算,那麼就越有平行化的價值。 在Java上得考量一種處理成本:基本資料型態與對應的包裹器型態間的轉換。例如,int 與Integer之間的Boxing與Unboxing操作。如果實際上List中都是數值且進行數學運算, 考慮使用mapToInt轉為專屬於int的IntStream,而後再進行數學運算,可免去不必要的 Boxing與Unboxing成本。目前就JDK8的Stream程式庫來說,也不建議對I/O做平行處理。 在想要免於I/O、同步處理等待之類情況下,其他並行、非同步I/O程式庫或 CompletableFuture會是比較好的選擇。 資料來源的結構也是一個考量,先前談過,可思考將有序打為無序後,是否對平行處理有 益,另一方面,因為平行處理必須分而治之,在這之前採取易於劃分的資料結構作為來源 ,對平行處理會有幫助,例如支援隨機存取的陣列、ArrayList或具有一定範圍的 IntStream.range,平行處理時會比較有效率;而HashSet、TreeSet等,因為涉及雜湊空 間與樹平衡等考量,會是其次之選;然而,像是LinkedList這類鏈結資料,走訪劃分資料 的成本是O(N),就不適合作為平行處理的來源結構,長度無法確定的資料來源,像是 Streams.iterate、BufferedReader.lines等,也不建議採用。 -- 良葛格學習筆記 http://openhome.cc -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 39.12.211.127 ※ 文章網址: https://www.ptt.cc/bbs/java/M.1449133393.A.7FB.html

12/03 23:30, , 1F
良葛格4ni
12/03 23:30, 1F
文章代碼(AID): #1MO0LHVx (java)
文章代碼(AID): #1MO0LHVx (java)