Raku-Kurs / Funktionale, nebenläufige, reaktive und Web-Programmierung / Nebenläufige Programmierung / hyper und race 🆕
Paralleles map mit hyper
Rufen Sie .hyper vor einem map oder
grep auf einer Liste auf, und die Arbeit verteilt sich über
mehrere Arbeits-Threads — während die Ergebnisse dennoch in der
ursprünglichen Reihenfolge zurückkommen:
say (1..5).hyper.map(* * 2); # (2 4 6 8 10)Das sieht genau aus wie ein gewöhnliches map, und das
Ergebnis ist gleich; der einzige Unterschied ist, dass die Verdopplungen
womöglich zugleich auf verschiedenen Kernen berechnet wurden.
.hyper arbeitet mit grep genauso — jedes
Element wird parallel geprüft, und die bestandenen kommen dennoch in
ihrer ursprünglichen Reihenfolge zurück:
say (1..10).hyper.grep(* %% 2); # (2 4 6 8 10)Da .hyper die Reihenfolge bewahrt, ist es ein
unmittelbarer Ersatz für ein langsames map oder
grep: Nichts, was von der Reihenfolge der Ergebnisse
abhängt, muss sich ändern. Der Gewinn zeigt sich erst, wenn die Arbeit
je Element groß genug ist, um die Kosten der Thread-Koordination
aufzuwiegen — eine Zahl zu quadrieren ist in Wirklichkeit viel zu
billig, um es zu parallelisieren. Für wirklich aufwendige Arbeit je
Element über eine große Liste kann .hyper ein langes Warten
für den Preis eines einzigen Methodenaufrufs in ein kurzes
verwandeln.
Eines ist zu bedenken: Ob die Arbeit tatsächlich über Kerne
verteilt wird, entscheidet der Compiler. Die Sprache legt die Ergebnisse
fest — und für .hyper ihre ursprüngliche Reihenfolge —,
verlangt aber keine wirkliche parallele Ausführung. .hyper
und .race bitten um Parallelität, statt
sie zu fordern, ein gegebener Compiler darf sie also auf einem
Threadpool ausführen oder die Elemente still der Reihe nach abarbeiten.
Betrachten Sie sie als Gelegenheit zur Beschleunigung, nicht als
Zusicherung einer solchen.
Weil die Reihenfolge bewahrt bleibt, kommen auch Operationen richtig heraus, die von ihr abhängen. Hier wird jedes Wort parallel großgeschrieben, und dennoch fügen sich die Stücke in ihrer ursprünglichen Reihenfolge wieder zum Satz:
say <raku is fun>.hyper.map(*.uc).join(' '); # RAKU IS FUNPraxis
Lösen Sie 1 Quiz zum Inhalt dieses Themas.
Kursnavigation
← hyper und race 🆕 | Quiz — hyper →
💪 Oder springen Sie direkt zu den Übungen dieses
Abschnitts.