2016-05-14 72 views
3

我被理查德·沃伯頓讀書的Java 8本書,與此想出了:爲什麼無序流比有序流更快?

一些操作都在有序流更加昂貴。通過消除排序,可以解決此問題 。爲此,請調用流的 unordered方法。 [...]

我很困惑。假設我們有Stream<Integer> stream = Arrays.asList(1, 2, 3, 4).stream();

由於List<Integer>定義遭遇訂單可能會被低效執行的操作流(一些)。這是爲什麼?

它是如何影響處理的,是什麼讓它變慢?爲了使事情更快,在這種情況下,我們應該稱之爲

Stream<Integer> stream = Arrays.asList(1, 2, 3, 4).stream().unordered(); 

?聽起來很奇怪,至少可以這樣說......

+0

「某些操作在訂購流上更貴」哪些操作是那些操作? – SMA

+0

查看[此](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)頁面上的'訂購'部分。解釋一切。 –

+0

您的報價不符合您的問題。 *有些操作*速度更快...不是流本身。 – EJP

回答

5

對此進行了詳細的文檔中解釋說: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

訂購
流可能會或可能不會有一個確定的遭遇秩序。 某個流是否有遇到順序取決於源和中間操作。 某些流源(例如List或 陣列)是內在排序的,而其他(如HashSet) 則不是。某些中間操作(如sorted())可能會在其他無序流上施加遭遇順序,而其他中間操作可能會使無序順序流(例如BaseStream.unordered())呈現無序狀態。 此外,一些終端操作可能會忽略遇到次序,例如forEach()的 。

如果一個流被排序,大多數操作都被限制在 上,如果流的源是包含[1,2,3]的列表,則執行map(x - > x * 2) 的結果必須是[2,4,6]。但是,如果源沒有定義遇到 的順序,那麼值[2,4,6]的任何置換將是有效的 結果。 對於順序流,遇到命令 的存在與否不會影響性能,只會影響確定性。如果一個流是有序的, 重複執行相同的流管道上相同的 源將產生相同的結果;如果未訂購,重複執行 可能會產生不同的結果。

對於並行流,放寬排序約束有時可以使 實現更高效的執行。如果 元素排序不相關,某些集合操作(​​例如 )可以更高效地實現過濾重複(distinct())或分組減少 (Collectors.groupingBy())。類似地,與碰到次序本質上相關的操作(如limit())可能需要緩衝以確保正確的排序,從而破壞了並行性的好處。 在流有碰到命令但用戶不特別關心該碰到命令的情況下,顯式地 使用無序()對該流解除排序可以提高某些有狀態或終端操作的並行性能。但是,大多數 流式管道,例如上面的「塊權重之和」示例, 仍然可以在排序約束下有效地並行化。

相關問題