我一直在研究scala和AKKA来管理一个明显可并行化的算法 . 我对函数式编程有一些了解,而且大部分都是Java,所以我的FP可能还不是最好的 .
我正在使用的算法非常简单,有一个顶级计算:
def computeFull(...): FullObject
此计算调用子计算,然后将其求和(以简化):
def computePartial(...): Int
和 computeFull
做这样的事情(再次简化):
val partials = for(x <- 1 to 10
y <- 1 to 10) yield computePartial(x, y)
partials.foldLeft(0)(_ + _)
因此,它非常接近AKKA示例,进行PI计算 . 我有很多可以调用的computeFull,并且每个都有很多computePartial . 所以我可以在AKKA演员中包装所有这些,或者简化Futures,在不同的线程中调用每个computeFull和每个computePartial . 然后我可以使用http://doc.akka.io/docs/akka/snapshot/scala/futures.html的折叠,拉链和 Map 功能来组合未来 .
但是,这意味着computeFull和computePartial必须返回包含实际结果的Futures . 因此,它们依赖于AKKA并假设事物并行运行 . 实际上,我还必须在函数中隐式传递执行上下文 .
我认为这很奇怪,算法“不应该”知道它是如何并行化的细节,或者它是否 .
在阅读了scala(而不是AKKA)中的Futures并查看Code Continuation之后 . 似乎scala(http://www.scala-lang.org/api/current/scala/Responder.html)提供的Responder monad似乎是抽象函数调用如何运行的正确方法 . 我有这种模糊的直觉,即computeFull和computePartial可以返回Responders而不是future,当monad执行时,它决定嵌入在Responder中的代码是如何执行的(如果它生成一个新的actor或者它是在同一个线程上执行的) ) .
但是,我不确定如何得到这个结果 . 有什么建议?你觉得我走的是正确的吗?
2 回答
如果你不想依赖Akka(但请注意,Akka风格的未来将被移动并包含在Scala 2.10中)并且你的计算是一个简单的折叠,你可以简单地使用Scala的并行集合:
当然,这将阻止,直到
partials
准备就绪,所以当你真的需要期货时,这可能不是一个合适的情况 .使用Scala 2.10样式期货,您可以完全异步,而无需您的算法注意到它:
所以,
computePartial
不需要知道它是如何被执行的 . (它不应该有任何副作用,即使为了这个例子的目的,包括了println
副作用 . )可能的
computeFull
方法应该管理算法,因此了解Futures
或并行性 . 毕竟这是算法的一部分 .(至于
Responder
:Scala的旧期货使用它,所以我不知道这是怎么回事 . - 并不是一个执行上下文正是你正在寻找的配置方式?)akka中的单身演员不知道他是否以平行方式奔跑 . 这就是akka的设计方式 . 但是如果你不想依赖akka,你可以使用并行集合,如:
在并行集合上调用和,并且以并行方式执行 .