Scala 2.9和Actors中的并行集合

时间:2011-04-09 22:36:58

标签: scala collections parallel-processing actor scala-2.9

好的,这可能是一个相当愚蠢的问题,但在actor框架中使用并行集合有什么好处?也就是说,如果我一次只从一个演员的邮箱处理一条消息,那么是否需要并行收集?并行集合和参与者是否相互排斥?什么是涉及两者的用例?

2 个答案:

答案 0 :(得分:15)

他们解决了不同的问题。演员善于解决task parallel problems。虽然并行集合善于解决data parallel problems。我不认为它们是互斥的 - 你可以在演员和包含演员的并行集合中使用并行集合。


编辑 - 快速测试: 即使像演员通知循环那样简单的事情也会受益。

在下面的代码中,我们注册了一个拥有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")

}

答案 1 :(得分:2)

Scala中的Actors库只是其中一个选项,并发方法,其中包括许多(线程和锁,STM,期货/承诺),它不应该用于各种问题,或者可以组合使用与一切(虽然演员和STM可以在一起做得很好)。在某些情况下,设置一组参与者(工人+主管)或明确地将任务分成若干部分,将它们提供给fork-join池,这太麻烦了,调用{{1}更方便在您已经使用的现有集合上,只需并行遍历它,几乎免费获得性能优势(在设置方面)。

总而言之,actor和并行集合是问题的不同维度 - actors是一个并发范例,而并行集合只是一个有用的工具,不应该被视为并发替代,而是作为集合的扩充工具集。