Sollte ich immer mit einem parallelen stream, wenn möglich?
Mit Java 8 und lambdas es ist einfach zu iterieren über Sammlungen von Datenströmen, und ebenso einfach in ein parallel-stream. Zwei Beispiele aus die docs, die zweite mit parallelStream:
myShapesCollection.stream()
.filter(e -> e.getColor() == Color.RED)
.forEach(e -> System.out.println(e.getName()));
myShapesCollection.parallelStream() //<-- This one uses parallel
.filter(e -> e.getColor() == Color.RED)
.forEach(e -> System.out.println(e.getName()));
Solange ich kümmern sich nicht um die Reihenfolge, wäre es immer von Vorteil sein, verwenden Sie die parallele? Man würde denken, es ist schneller, die Aufteilung der Arbeit auf mehrere Kerne.
Gibt es andere überlegungen? Wann sollte parallel stream verwendet werden, und Wann sollten die nicht parallel verwendet werden?
(Diese Frage wird gebeten, die trigger eine Diskussion darüber, wie und Wann die Nutzung paralleler streams, nicht weil ich denke, dass immer mit Ihnen ist eine gute Idee.)
InformationsquelleAutor Matsemann | 2013-12-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen parallelen stream hat eine viel höhere Aufwand im Vergleich zu einer sequentiellen. Die Koordination der threads dauert eine erhebliche Menge an Zeit. Ich würde sequentielle streams von Standard-und nur parallel, wenn
Habe ich eine riesige Menge von Elementen zu verarbeiten (oder die Verarbeitung der einzelnen Artikel erfordert Zeit und ist parallelisierbare)
Ich habe ein performance-problem in den ersten Platz
Ich nicht schon die Ausführung des Prozesses in einem multi-thread-Umgebung (zum Beispiel: in einem web container, wenn ich schon viele Anfragen parallel verarbeitet, das hinzufügen einer zusätzlichen Schicht von Parallelität innerhalb jeder Anfrage könnte mehr negative als positive Effekte)
In deinem Beispiel, die Leistung wird sowieso Gefahren werden durch den synchronisierten Zugriff auf
System.out.println()
, und was diesen Prozess parallel haben keine Wirkung oder sogar eine negative.Darüber hinaus, denken Sie daran, dass parallel streams nicht magisch lösen alle Probleme bei der Synchronisierung. Wenn eine freigegebene Ressource verwendet wird, die von den Prädikaten und Funktionen in den Prozess, werden Sie haben, um sicherzustellen, dass alles ist thread-sicher. Insbesondere, Nebenwirkungen sind Dinge, die Sie wirklich haben, um über sorgen, wenn Sie gehen parallel.
In jedem Fall Messen, nicht schätzen! Nur eine Messung, die wird Ihnen sagen, wenn die Parallelität der es Wert ist oder nicht.
Ich bin nicht einverstanden. Die Fork/Join-system wird die einfache Aufteilung der N Objekte in z.B. 4 Teile und verarbeiten diese 4 Teile nacheinander. Die 4 Ergebnisse werden dann reduziert. Wenn massive, wirklich massive, auch zur schnellen Einheit, Verarbeitung, Parallelisierung effektiv sein können. Aber wie immer, Sie haben zu Messen.
ich habe eine Sammlung von Objekten, die Umsetzung
Runnable
das nenne ichstart()
Sie alsThreads
, ist es ok, um zu ändern, dass die Verwendung von java 8 streams in einer.forEach()
parallelisiert ? Dann würde ich in der Lage zu Streifen, den thread-code aus der Klasse. Aber gibt es irgendwelche Nachteile?Wenn 4 Teile besitzen nacheinander, dann gibt es keinen Unterschied, dass es parallelen Prozess oder sequentiell wissen? Pls klären
er bedeutet offensichtlich, dass die Elemente von jedem der 4 Teile der Reihe nach verarbeitet werden. Jedoch, die Teile selbst können gleichzeitig bearbeitet werden. In anderen Worten, wenn Sie mehrere CPU-Kerne verfügbar sind, kann jeder Teil auf seine eigene Kern unabhängig von den anderen teilen, die während der Bearbeitung Ihre eigenen Elemente nacheinander. (HINWEIS: ich weiß nicht, ob dies ist, wie die parallele Java-streams arbeiten, ich versuche nur zu klären, was JBNizet gemeint.)
InformationsquelleAutor JB Nizet
Die Stream-API wurde entwickelt, um machen es einfach zu schreiben, Berechnungen in einer Weise abstrahiert von der Frage, wie Sie ausgeführt werden würde, so dass die Umschaltung zwischen der sequenziellen und parallelen leicht.
Aber nur weil es einfach ist, bedeutet nicht, es ist immer eine gute Idee, und in der Tat, es ist ein bad Idee, einfach
.parallel()
alle über dem Platz, einfach, weil Sie können.Beachten Sie zunächst, dass Parallelität bietet keine Vorteile, außer der Möglichkeit schneller Ausführung bei mehr cores verfügbar sind. Eine parallele Ausführung wird immer mit mehr Arbeit als eine sequenzielle, denn neben der Lösung des Problems, es hat auch zur Durchführung Disposition und Koordination von Teilaufgaben. Die Hoffnung, dass Sie werde in der Lage sein, die Antwort schneller durch die Aufteilung der Arbeit auf mehrere Prozessoren; ob dies tatsächlich geschieht, hängt von vielen Dingen ab, einschließlich der Größe der Daten festlegen, wie viel Berechnung Sie auf jedes element, die Art der Berechnung (insbesondere, stellt die Verarbeitung von einem element interagieren mit der Verarbeitung von anderen?), die Anzahl der verfügbaren Prozessoren und die Anzahl der Aufgaben im Wettbewerb um die Prozessoren.
Weiter, beachten Sie, dass sich die Parallelität auch oft macht nondeterminism in die Berechnung, ist oft verdeckt durch sequentielle Implementierungen; manchmal ist dies nicht relevant, oder kann gemildert werden durch Immobilisierung der beteiligten Betriebe (d.h., Reduzierung müssen die Betreiber Staatenlose und assoziativ.)
In der Realität, manchmal Parallelität beschleunigen die Berechnung, manchmal nicht, und manchmal wird es sogar langsamer. Am besten ist es, sich erst entwickeln, mit Hilfe von sequentiellen Ausführung und wenden Sie dann die Parallelität in denen (A) Sie wissen, dass es tatsächlich nutzen, um die Leistung erhöht und (B), dass es tatsächlich eine gesteigerte Leistung. (A) ist ein business-problem, nicht ein technisches. Wenn Sie ein performance-Experte sind, Sie werden in der Regel in der Lage sein Blick auf den code, und ermitteln Sie (B), aber der smart Weg ist zu Messen. (Und nicht einmal die Mühe, bis du überzeugt bist von (A); wenn der code schnell genug ist, besser um Ihre Gehirn-Zyklen an anderer Stelle.)
Die einfachste performance-Modell für Parallelität in den "NQ" - Modell, wobei N die Anzahl der Elemente, und F ist die Berechnung pro element. Im Allgemeinen müssen Sie das Produkt NQ überschreitet eine Schwelle, bevor Sie anfangen, ein performance-Vorteil. Für eine low-Q problem wie "addieren von zahlen von 1 bis N", werden Sie in der Regel sehen einen breakeven zwischen N=1000 und N=10000. Mit höheren Q Probleme, du wirst sehen, breakevens bei niedrigeren Schwellenwerten.
Aber die Realität ist ziemlich kompliziert. So, bis Sie erreichen experthood, müssen Sie zuerst ermitteln, wenn die sequentielle Verarbeitung ist eigentlich kostet Sie etwas, und dann Messen, ob Parallelität helfen.
Ich bin mir nicht sicher, ob ich verstehe Ihre Frage-sind Sie auf der Suche nach jemandem zu erklären, warum mehrere parallele threads machen Berechnung nondeterminstic?
schalten einen Strom von sequentiellen zu parallelen ändern Sie den Algorithmus (in den meisten Fällen). Der Determinismus, der hier erwähnt ist, ist in Bezug auf Ihre Eigenschaften (beliebige) Operatoren könnte sich verlassen auf (die Stream-Implementierung kann nicht wissen, dass), aber natürlich ist sollte nicht verlassen. Das ist es, was diesen Abschnitt dieser Antwort versucht zu sagen. Wenn Sie sich sorgen über die Regeln, die Sie haben können, ein deterministisches Ergebnis, wie Sie sagen, (ansonsten parallelen streams waren ziemlich nutzlos), aber es gibt auch die Möglichkeit, absichtlich erlaubt, nicht-Determinismus, wie bei der Verwendung von
findAny
stattfindFirst
..."Erstens ist zu beachten, dass sich die Parallelität bietet keine Vorteile, außer der Möglichkeit der schnelleren Ausführung, wenn mehr Kerne vorhanden sind" -- oder, wenn Sie anwenden, eine Aktion, die beinhaltet, IO (z.B.
myListOfURLs.stream().map((url) -> downloadPage(url))...
).Das ist eine schöne Theorie, aber leider naiv (siehe die 30-jährige Geschichte der Bemühungen um den Aufbau von auto-Parallelisierung-Compiler für den start). Da es nicht praktikabel ist, richtig zu raten genug Zeit, um nicht den Benutzer zu ärgern, wenn wir unweigerlich bekommen es falsch, die Verantwortung, was zu tun war, nur, damit die Benutzer zu sagen, was Sie wollen. Für die meisten Situationen, die Standard - (sequentielle) richtig ist, und mehr voraussagbar.
InformationsquelleAutor Brian Goetz
Sah ich eine der Präsentationen von Brian Goetz (Java Language Architect & Spezifikation führen für Lambda-Ausdrücke). Er erklärt im detail die folgenden 4 Punkte beachten, bevor Sie gehen für Parallelisierung:
Aufteilung /ZERLEGUNG Kosten
– Manchmal Spaltung ist teurer als nur die Arbeit machen!
Task-Versand /- management, Kosten
– Können tun eine Menge Arbeit in die Zeit, die es braucht, um Handarbeit zu einem anderen thread.
Ergebnis Kombination Kosten
– Manchmal Kombination umfasst das kopieren von vielen Daten. Zum Beispiel durch das hinzufügen von zahlen ist Billig in der Erwägung, dass die Zusammenführung von Mengen ist teuer.
Lokalität
– Der Elefant im Zimmer. Dies ist ein wichtiger Punkt, dem jeder entgehen. Sollten Sie erwägen den cache findet, wenn eine CPU wartet auf die Daten, da der cache findet, dann würden Sie nicht alles gewinnen durch Parallelisierung. Das ist, warum array-basierten Quellen parallelisieren, die am besten als der nächste-Indizes (in der Nähe des aktuellen index) zwischengespeichert werden, und es gibt weniger Chancen, dass die CPU würde ein cache-miss.
Er erwähnt auch eine relativ einfache Formel, um zu bestimmen, eine Möglichkeit des parallelen speedup.
NQ Modell:
wo
N = Anzahl der Daten-Objekte
Q = Menge der Arbeit pro Artikel
InformationsquelleAutor Ram Patra
JB trifft den Nagel auf den Kopf. Das einzige, was ich hinzufügen kann ist, dass Java8 nicht rein parallele Verarbeitung, es tut paraquential ich ja den Artikel geschrieben und das hab ich getan, F/J für dreißig Jahre, so verstehe ich das Problem.
Stream hat eine iterator () - Methode, so dass Sie können Durchlaufen Sie externe, wenn Sie wollen. Mein Verständnis war, dass Sie nicht implementieren Iterierbar, da kann man nur den iterator einmal, und niemand konnte entscheiden, ob das OK war.
um ehrlich zu sein : Ihre ganze Papier liest sich wie eine massive, aufwendige schimpfen - und das ziemlich negiert seine Glaubwürdigkeit ... würde ich empfehlen, wieder tut es mit einem viel weniger aggressiven Unterton, ansonsten nicht viele Leute tatsächlich die Mühe, vollständig zu Lesen ... im just sayan
Ein paar Fragen zu deinem Artikel... erstmal, warum Sie anscheinend gleichzusetzen symmetrische Strukturen mit gerichteten azyklischen Graphen? Ja, ausgeglichene Bäume DAGs, aber so sind verknüpfte Listen, und so ziemlich jedes Objekt-orientierte Datenstruktur anderes als arrays. Auch, wenn Sie sagen, rekursive Dekomposition funktioniert nur auf ausgewogene Strukturen und ist daher nicht relevant, kommerziell, wie begründen Sie diese Behauptung? Es scheint mir (zugegeben, ohne Sie wirklich zu untersuchen, das Problem in der Tiefe), dass es funktionieren sollte ebenso array-basierte Datenstrukturen, z.B.
ArrayList
/HashMap
.Dieser thread ist von 2013, hat sich einiges verändert. Dieser Bereich ist für Kommentare, die nicht ausführliche Antworten.
InformationsquelleAutor edharned
Anderen Antworten bereits abgedeckt profiling zu vermeiden, vorzeitige Optimierung und overhead-Kosten bei der parallelen Verarbeitung. Diese Antwort erklärt, die ideale Wahl der Datenstrukturen für parallele streaming.
Quelle: Item #48 Vorsicht Bei Machen Streams Parallel, Effektive Java-3e von Joshua Bloch
InformationsquelleAutor ruhong