2016-01-06 80 views
4

在大多數情況下,Java 8流允許比老式的for循環更易讀的代碼。但是,根據我自己的經驗和我讀過的內容,使用流而不是for循環可能涉及性能受到影響(或偶爾會有改善),有時難以預測。Java 8流將比for循環運行慢的關鍵指標?

在一個大的項目似乎並沒有寫每一個循環的基準測試是可行的,所以決定是否與流替換for循環時,有哪些關鍵因素(如預期集合的大小,通過過濾去除的值的預期百分比,迭代操作的複雜性,減少或聚集的類型等)哪些可能指示將導致性能改變?

注:這是my earlier question縮小,這是關閉範圍過寬(和其並行數據流的方面進行了很好覆蓋in another SO question),所以我們只限於這連續流。

+11

病例的99%以上,答案很簡單:寫的是代碼的清晰,可讀,可維護,顯然是正確的。雖然人們可以無休止地關注性能,但在大多數情況下,以美元衡量的實際成本差異爲零(因爲大部分代碼「足夠快」)。另一方面,認爲錯誤可能會產生真正的美元成本。 (而且,如果你只有不到1%的人需要爲表現煩惱,那麼你已經知道了,而且你已經在測量方法上做了大量投資。) –

+0

感謝那些回答或評論的人。我的問題是基於法國雜誌上的一篇文章(Programmez,2016年1月),其中一些顧問分支了一個B2C網站的代碼並重構以用流替換許多'for'循環。基於性能測試(方法執行時間在最差情況下大致增加了一倍),他們無法說服產品所有者繼續在主分支中進行重構。很難將產品所有者推銷爲「我們將花費一週時間改進代碼,我們不會添加任何功能,產品運行速度會更慢」。 –

回答

19

它不僅是「寫的每一個循環的基準測試不可行的」,這是適得其反。一個特定的,特定於應用程序的循環在進入微基準時可能會完全不同。

對於實際應用,優化的標準規則適用:不這樣做。只要寫什麼是更具可讀性和只有存在性能問題,輪廓整個應用檢查特定的循環或流使用是否真的是瓶頸。只有在這種情況下,你纔可以嘗試在兩個習慣用語之間切換,看看它是否有所作爲。

在大多數情況下,它不會。如果存在真正的性能問題,則它將源於操作的類型,例如,執行具有O(n²)時間複雜度的嵌套迭代等。這些問題不取決於您是使用Stream還是使用for循環,並且這兩個成語之間的次要性能差異不會改變您的代碼如何縮放

+1

經過一番思考,我決定選擇這個作爲答案。這個問題得到了2個寫得很好,理由充分的答案以及來自世界知名專家的智能評論。我想要一個可以在代碼評論中使用的解決方案來獲得2倍速度的預先提交,但也許這是不可能的。我選擇了這個答案,因爲在性能敏感的代碼中,用流代替循環的最好方法是以增量方式進行,如果性能問題被自動化的端到端測試檢測到,則可以輕鬆地將其退出。 –

6

streamsloops之間沒有很大的總體速度差異,它們的優點/缺點是特定於問題的。無論你選擇哪一個,都應該依賴於代碼的可讀性(大部分)。對於一些性能比較,看Benchmark1Benchmark2在那裏你可以看到作者Brian Goetz的評論的答案之一:

您對性能的結論,而有效的,是誇大了。在很多情況下,流代碼比迭代代碼更快,主要是因爲按元素訪問成本比使用流迭代器更便宜。並且在很多情況下,流版本內聯到相當於手寫版本的東西。當然,魔鬼是在細節中;任何給定的代碼位可能會有不同的表現。

除此之外,只要確保在基準測試時使用JMH即可。