Bru*_*son 11 collections parallel-processing scala actor scala-2.9
好吧,这可能是一个相当愚蠢的问题,但在actor框架中使用并行集合有什么好处?也就是说,如果我一次只从一个演员的邮箱处理一条消息,那么是否需要并行收集?并行集合和参与者是否相互排斥?什么是涉及两者的用例?
Joh*_*loo 15
他们解决不同的问题.演员善于解决任务并行问题.虽然并行集合擅长解决数据并行问题.我不认为它们是互斥的 - 您可以在actor和包含actor的并行集合中使用并行集合.
编辑 - 快速测试:甚至像演员通知循环这样简单的好处.
在下面的代码中,我们注册了一个拥有actor注册表的一百万个actor,它必须通知他们一个事件.
非并行通知循环(registry foreach {})在我的机器上平均需要2.8秒(4核2.5 GHz笔记本电脑).当使用并行收集循环(registry.par.foreach {})时,它需要1.2秒并使用所有四个核心.
import actors.Actor
case class Register(actor: Actor)
case class Unregister(actor: Actor)
case class Message( contents: String )
object ActorRegistry extends Actor{
var registry: Set[Actor] = Set.empty
def act() {
loop{
react{
case reg: Register => register( reg.actor )
case unreg: Unregister => unregister( unreg.actor )
case message: Message => fire( message )
}
}
}
def register(reg: Actor) { registry += reg }
def unregister(unreg: Actor) { registry -= unreg }
def fire(msg: Message){
val starttime = System.currentTimeMillis()
registry.par.foreach { client => client ! msg } //swap registry foreach for single th
val endtime = System.currentTimeMillis()
println("elapsed: " + (endtime - starttime) + " ms")
}
}
class Client(id: Long) extends Actor{
var lastmsg = ""
def act() {
loop{
react{
case msg: Message => got(msg.contents)
}
}
}
def got(msg: String) {
lastmsg = msg
}
}
object Main extends App {
ActorRegistry.start
for (i <- 1 to 1000000) {
var client = new Client(i)
client.start
ActorRegistry ! Register( client )
}
ActorRegistry ! Message("One")
Thread.sleep(6000)
ActorRegistry ! Message("Two")
Thread.sleep(6000)
ActorRegistry ! Message("Three")
}
Run Code Online (Sandbox Code Playgroud)