scala中是否有快速并发语法sugar的实现?地图缩小

scala中是否有快速并发语法sugar的实现?地图缩小,scala,concurrency,mapreduce,syntactic-sugar,Scala,Concurrency,Mapreduce,Syntactic Sugar,和演员们一起传递信息非常棒。但我希望有更简单的代码 示例(伪代码) 其中,将一个大列表转换为100个小列表 numberofactors部分创建一个池,该池使用5个参与者,并在作业完成后接收新作业 getallresults在列表中使用一个方法。所有这些都是通过在后台传递消息来完成的。其中可能是getFirstResult,计算第一个结果,并停止所有其他线程(如破解密码)您可以使用的并发功能来实现您想要的 import scalaz._ import Scalaz._ import concur

和演员们一起传递信息非常棒。但我希望有更简单的代码

示例(伪代码)

其中,将一个大列表转换为100个小列表 numberofactors部分创建一个池,该池使用5个参与者,并在作业完成后接收新作业 getallresults在列表中使用一个方法。所有这些都是通过在后台传递消息来完成的。其中可能是getFirstResult,计算第一个结果,并停止所有其他线程(如破解密码)

您可以使用的并发功能来实现您想要的

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,它在一个函数中完成拆分和折叠)。此外,列表上的parMap也不必要地严格。您需要在整个列表准备好之前开始折叠。更像:

val splicedList = biglist.grouped(100).toList
val sum = splicedList.map(promise(_.sum)).toStream.traverse(_.sum).get

在2010年的Scala日上,Aleksandar Prokopec(他在EPFL从事Scala的工作)进行了一次非常有趣的演讲。这可能会出现在2.8.1中,但您可能需要等待更长的时间。如果我能亲自做演示,我会去看的。链接到这里


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

您可以用比使用futures创建参与者更少的开销来完成这项工作:

import scala.actors.Futures._
val nums = (1 to 1000).grouped(100).toList
val parts = nums.map(n => future { n.reduceLeft(_ + _) })
val whole = (0 /: parts)(_ + _())
您必须处理分解问题、编写“未来”块并将其重新组合为最终答案的问题,但这确实使并行执行一堆小代码块变得容易

(请注意,左折中的
\(
)是未来的应用函数,意思是“给我你并行计算的答案!”,它会一直阻塞,直到答案可用为止。)


并行集合库将自动分解问题并为您重新组合答案(如Clojure中的
pmap
);这还不是主API的一部分。

我不是在等待Scala 2.8.1或2.9,最好是编写自己的库或使用另一个库,所以我在谷歌上搜索了更多,找到了这个:akka

它有一个对象和方法

awaitAll(futures: List[Future]): Unit
awaitOne(futures: List[Future]): Future
但是 没有任何文档。那太糟糕了

但好的方面是akka的演员比scala的本地演员更苗条

有了所有这些库(包括scalaz),如果scala本身最终能够将它们与2.8.1中包含的scala并行集合正式合并,那就太好了。您将能够执行以下操作:

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版《夜间睡》,您将能够尝试并行收集。

要将任何收集转换为并行版本,您只需要一个
PromiseT[M]
monad transformer,它与M[Promise[a]]同构。从PromiseT[M]#Apply[A]到M[A]的隐式转换将使转换器完全透明。2.8.1?什么时候发布?是的,我看到了
getAllResults
,但是
getfirstresults和throwawayeverythingelsefunction
呢?我们不需要使用
all
,而是需要
any
,现在需要做更多的工作——记住,在任何语言中都不是很有效——并且需要将
future
替换为
actor{loop{react{/*case code*/}}!消息
,然后接收第一个回复并忽略其余回复。无论如何,重点是,您当然可以用参与者构建它(即使使用自动退出,如果您使用链接),但它不是现成的。改进的并发性是2.9.2.9的主要关注点之一?那是什么时候?或者我应该问Scala什么时候可以用于主要生产用途?(是的,有推特,但是,只有推特)2.9不会很快准备好让你在你想要回答这个问题的时间尺度上使用它。关键是,你不是唯一一个认识到这些事情会很好的人,并且正在计划改进。在此之前,您可以创建所需的功能,但需要使用较低级别的构造(Java线程和/或Scala参与者)进行更多的工作。我发现scalaz的文档太差,无法用于生产使用,我希望几个月后它会变得更好。我们正在编写文档。但是代码非常简单,所以摸索源代码是下一个最好的方法,这看起来非常棒。我想foldLeft也可以在这里工作
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