4

アクターとメッセージをやり取りするのは素晴らしいことです。しかし、もっと簡単なコードが欲しいです。

例(擬似コード)

val splicedList:List[List[Int]]=biglist.partition(100)
val sum:Int=ActorPool.numberOfActors(5).getAllResults(splicedList,foldLeft(_+_))

ここで、spliceIntoPartsは1つの大きなリストを100の小さなリストに変換し、numberofactors部分を作成し、5つのアクターを使用するプールを作成し、ジョブの終了後に新しいジョブを受け取り、getallresultsはリストのメソッドを使用します。これはすべて、メッセージがバックグラウンドで渡されることで行われます。ここで、おそらくgetFirstResultは、最初の結果を計算し、他のすべてのスレッドを停止します(パスワードの解読など)

4

5 に答える 5

4

2.8.1 に含まれる Scala Parallel コレクションを使用すると、次のようなことができるようになります。

val spliced = myList.par // obtain a parallel version of your collection (all operations are parallel)
spliced.map(process _)   // maps each entry into a corresponding entry using `process`
spliced.find(check _)    // searches the collection until it finds an element for which
                         // `check` returns true, at which point the search stops, and the element is returned

コードは自動的に並行して実行されます。通常のコレクション ライブラリにある他のメソッドも同様に並列化されています。

現在、2.8.RC2 は非常に近く (今週または来週)、2.8 の最終版は数週間後に来ると思います。2.8.1 nightlies を使用すると、並列コレクションを試すことができます。

于 2010-04-29T13:11:19.577 に答える
3

Scalazの同時実行機能を使用して、目的を達成できます。

import scalaz._
import Scalaz._
import concurrent.strategy.Executor
import java.util.concurrent.Executors

implicit val s = Executor.strategy[Unit](Executors.newFixedThreadPool(5))

val splicedList = biglist.grouped(100).toList
val sum = splicedList.parMap(_.sum).map(_.sum).get

これをよりきれいにするのはかなり簡単です (つまり、分割と折りたたみをすべて 1 つに行う関数 mapReduce を記述します)。また、リストに対する parMap は不必要に厳密です。リスト全体の準備が整う前に、折りたたみを開始する必要があります。もっと好き:

val splicedList = biglist.grouped(100).toList
val sum = splicedList.map(promise(_.sum)).toStream.traverse(_.sum).get
于 2010-04-28T12:53:59.923 に答える
2

先物を使用してアクターを作成するよりも少ないオーバーヘッドでこれを行うことができます。

import scala.actors.Futures._
val nums = (1 to 1000).grouped(100).toList
val parts = nums.map(n => future { n.reduceLeft(_ + _) })
val whole = (0 /: parts)(_ + _())

問題を分解し、「future」ブロックを記述して最終的な答えに再構成する必要がありますが、それにより、多数の小さなコードブロックを並行して実行することが容易になります。

_()左の折り目はfutureの適用関数であり、「並列で計算していた答えを教えてください」という意味であり、答えが利用可能になるまでブロックされることに注意してください。)

pmap並列コレクションライブラリは、問題を自動的に分解し、( Clojureの場合と同様に)答えを再構成します。これはまだメインAPIの一部ではありません。

于 2010-04-28T15:07:20.397 に答える
2

Scala 2.8.1 や 2.9 を待っているわけではありません。独自のライブラリを作成するか、別のライブラリを使用する方がよいので、さらにグーグルで調べたところ、akka http://doc.akkasource.org/actorsが見つかりました。

メソッドを持つオブジェクト先物を持つ

awaitAll(futures: List[Future]): Unit
awaitOne(futures: List[Future]): Future

しかしhttp://scalablesolutions.se/akka/api/akka-core-0.8.1/ にはドキュメントがまったくありません。良くないね。

しかし良い点は、akka のアクターは scala のネイティブ アクターよりも
無駄が少ないということです これらのライブラリ (scalaz を含む) がすべて揃っているので、最終的に scala 自体がそれらを公式にマージできれば本当に素晴らしいことです

于 2010-04-29T03:44:01.053 に答える
1

Scala Days 2010 で、Aleksandar Prokopec (EPFL で Scala に取り組んでいる) によるParallel Collectionsに関する非常に興味深い講演がありました。これはおそらく 2.8.1 に含まれる予定ですが、もう少し待つ必要があるかもしれません。プレゼンテーション自体を取得できるかどうかを確認します。ここにリンクします。

アイデアは、あなたが提案したとおりに実行することによってコレクションの処理を並列化するコレクションフレームワークを持つことですが、ユーザーには透過的です。理論的には、インポートを scala.collections から scala.parallel.collections に変更するだけです。実行していることが実際に並列化できるかどうかを確認するために、明らかに作業を行う必要があります。

于 2010-04-28T14:16:32.893 に答える