2016-05-14 8 views
3

lese ich Java 8 Buch von Richard Warburton und kam mit dieser:Warum ist ein ungeordneter Stream schneller als ein bestellter Stream?

Einige Betrieb sind auf geordneten Strom teurer. Dieses Problem kann durch Beseitigen der Bestellung gelöst werden. Rufen Sie dazu die Methode unordered des Streams auf. [...]

Ich war ziemlich verblüfft davon. Angenommen, wir haben Stream<Integer> stream = Arrays.asList(1, 2, 3, 4).stream();

Seit List<Integer> definiert eine Begegnung um den Strom (einige) Betrieb könnte ineffizient durchgeführt werden. Warum das?

Wie beeinflusst es die Verarbeitung und was macht es langsam? Um die Dinge in diesem Fall schneller zu machen, sollten wir es so nennen:

? Klingt komisch, gelinde gesagt ...

+0

"Einige Operationen sind teurer auf bestellten Strom" welche Operation sind diese? – SMA

+0

Überprüfen Sie den Abschnitt 'Bestellung' auf der Seite [this] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html). Erklärt alles. –

+0

Ihr Angebot stimmt nicht mit Ihrer Frage überein. * Einige Operationen * sind schneller ... Nicht der Stream selbst. – EJP

Antwort

5

Dieses ausführlich in der Dokumentation erklärt: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html


Streams Bestellung kann oder keine definierte Begegnung Ordnung haben. Ob ein Stream eine Begegnungsreihenfolge hat oder nicht, hängt von der Quelle und den Zwischenoperationen ab. Bestimmte Stream-Quellen (z. B. List- oder -Arrays) sind intrinsisch geordnet, während andere (wie HashSet) nicht sind. Einige Zwischenoperationen, wie sorted(), erzwingen möglicherweise eine Aufeinandertreffreihenfolge in einem ansonsten ungeordneten Stream, und andere können einen geordneten Stream ungeordnet rendern, z. B. BaseStream.unordered(). Außerdem können einige Terminaloperationen die Reihenfolge der Aufrufe ignorieren, z. B. forEach().

Wenn ein Stream bestellt wird, sind die meisten Operationen auf die Elemente in ihrer Aufeinanderfolge angewiesen. Wenn die Quelle eines Streams eine Liste mit [1, 2, 3] ist, muss das Ergebnis der Ausführung von map (x -> x * 2) [2, 4, 6] sein. Wenn die Quelle jedoch keine definierte Reihenfolge hat, wäre jede Permutation der Werte [2, 4, 6] ein gültiges Ergebnis. Bei sequenziellen Streams beeinflusst das Vorhandensein oder Nichtvorhandensein einer Encounter-Reihenfolge nicht die Leistung, sondern nur den Determinismus. Wenn ein Stream bestellt wird, wird wiederholte Ausführung von identischen Stream-Pipelines auf einer identischen Quelle ein identisches Ergebnis erzeugen; Wenn es nicht bestellt wird, kann wiederholte Ausführung andere Ergebnisse erzeugen.

Bei parallelen Streams kann das Entsperren der Ordnungseinschränkung manchmal eine effizientere Ausführung von ermöglichen. Bestimmte Aggregatoperationen, wie Filterdubletten (distinct()) oder gruppierte Reduzierungen (Collectors.groupingBy()) können effizienter implementiert werden, wenn die Reihenfolge der Elemente nicht relevant ist.In ähnlicher Weise können Operationen, die intrinsisch gebunden sind, um auf die Reihenfolge zu stoßen, wie limit(), Pufferung erfordern, um eine ordnungsgemäße Bestellung sicherzustellen, wodurch der Vorteil von Parallelität untergraben wird. In Fällen, in denen der Stream eine Auffindungsreihenfolge hat, aber der Benutzer sich nicht sonderlich darum kümmert, kann die explizite De-Sortierung des Streams mit ungeordneter() die parallele Leistung für einige Stateful- oder Terminal-Operationen verbessern. Aber die meisten Stream-Pipelines, wie zum Beispiel die "Summe der Gewicht der Blöcke" Beispiel, noch effizient auch unter Ordnungsbeschränkungen parallelisieren.

Verwandte Themen