4

与演员一起传递信息很棒。但我想要更简单的代码。

示例(伪代码)

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

其中 spliceIntoParts 将一个大列表变成 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

让这个更漂亮会很容易(即编写一个函数 mapReduce 将拆分和折叠合二为一)。此外,List 上的 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)(_ + _())

您必须处理分解问题并编写“未来”块并将其重新组合成最终答案,但这确实使并行执行一堆小代码块变得容易。

(请注意,_()左侧折叠的是未来的应用功能,这意味着,“给我你正在并行计算的答案!”,它会阻塞,直到答案可用。)

并行集合库会自动分解问题并为您重新组合答案(就像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

在 2010 年 Scala Days 上,Aleksandar Prokopec(在 EPFL 从事 Scala 工作)发表了一个非常有趣的关于Parallel Collections的演讲。这可能会在 2.8.1 中,但您可能需要等待更长时间。我会看看我能不能得到演示文稿本身。在此处链接。

这个想法是有一个集合框架,它通过完全按照您的建议来并行化集合的处理,但对用户透明。理论上,您只需将导入从 scala.collections 更改为 scala.parallel.collections。显然,您仍然需要做一些工作,看看您正在做的事情是否真的可以并行化。

于 2010-04-28T14:16:32.893 回答