Gleichzeitige anzeigen/foreach in scala
Ich habe eine iteration vals: Iterable[T]
und eine lang andauernde Funktion ohne relevante Nebenwirkungen: f: (T => Unit)
. Das ist im Augenblick angewendet, um vals
in der offensichtlichen Weise:
vals.foreach(f)
Ich würde gerne die Aufrufe f
zu tun, die gleichzeitig (innerhalb vernünftiger Grenzen). Ist es eine offensichtliche Funktion, die irgendwo in der Scala Basis-Bibliothek? So etwas wie:
Concurrent.foreach(8 /* Number of threads. */)(vals, f)
Während f
ist ziemlich lange laufen, es ist kurz genug, dass ich nicht wollen, dass der overhead für den Aufruf einer thread für jeden Anruf, also ich bin auf der Suche nach etwas, das basierend auf einem thread-pool.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich mag die
Futures
Antwort. Jedoch, während es parallel ausgeführt werden, wird es auch wieder asynchron, was wahrscheinlich nicht das, was Sie wollen. Der richtige Ansatz wäre wie folgt:vals
ist eine strenge Sammlung-wenn es faul ist (und in Scala 2.7 dieses umfasst dieRange
Klasse), die futures nicht erstellt werden, bis jeder einen benötigtforeach
, und es wird nichts geschehen parallel.foreach
Anruf zwischen dermap
und die aktuellenforeach
. Also:vals map { x => future { f(x) } } foreach { x => x } foreach { _() }
foreach
war (natürlich) die falsche Sache zu injizieren, da gibt esUnit
. Mein schlechtes! 🙂 Diemap
Funktion auf lazy collections ist fast immer non-strict, so können wir entweder rufentoList
(odertoArray
), oder wir können das Projekt und dann force:(vals map { x => future { f(x) } } projection).force foreach { _() }
. Ich weiß nicht, ob das besser als einfachtoList
, aber es ist sicherlich anders.Viele der Antworten von 2009 noch die alte scala.Akteure.Futures._, die sind nicht mehr in den neueren Scala. Während Akka ist der bevorzugte Weg, ein viel mehr lesbar ist, verwenden Sie einfach parallel (.par) Sammlungen:
vals.foreach { v => f(v) }
wird
vals.par.foreach { v => f(v) }
Alternativ mit parMap erscheinen kann, kurz und bündig, wenn auch mit der Einschränkung, dass Sie sich merken müssen, importieren Sie die üblichen Scalaz*. Wie üblich, gibt es mehr als einen Weg, um das gleiche zu tun in der Scala!!
Scalaz hat
parMap
. Sie würde es verwenden, wie folgt:Dieser Ausrüstung jeder Funktor (einschließlich
Iterable
) mit einemparMap
Methode, so können Sie nur:Erhalten Sie auch
parFlatMap
,parZipWith
usw.Hatte ich einige Probleme mit scala.Akteure.Futures in Scala 2.8 (es war buggy, wenn ich überprüft). Mit java-libs direkt für mich gearbeitet, obwohl:
Ich würde verwenden
scala.actors.Futures
:Die neueste Version von Funktionale Java hat einige höher -, um concurrency-features, die Sie verwenden können.
Und dann...
Erinnern zu
shutdown
diepool
.Können Sie die Parallel Sammlungen aus der Scala-standard-Bibliothek.
Sie sind genauso wie normale Sammlungen, aber Ihre Operationen parallel ausführen. Sie müssen nur ein
par
rufen Sie vor dem Aufruf einige Sammlungen Betrieb.