在这种情况下,Scala和akka切换到可变数据收集?

时间:2013-11-13 09:32:12

标签: scala functional-programming akka immutability

我突然意识到在功能上写起来真的不太难,所以我决定从我的代码中重构我的一些工作中删除可变集合。这个地方正在消失。现在我处于一个点,我有一个Seq代表一个被监督的演员集合,每次完成一个我需要从序列中删除它。我想在功能上你会创建一个新的seq并用新序列做一个akka。

def shepherd(categories: Seq[ActorRef]) : Receive = {
  case ForumCrawler.Done() => {
    val new_categories = categories.filter(a => a != sender)
    if(new_categories.size == 0) {
      println("all done")
      system.shutdown()
    }
   context.become(shepherd(new_categories))
}

当演员序列在10k区域时,这仍然是一种可行的方法吗? scala是否会以某种方式改变幕后的序列,或者我将获得一整套来设置副本?

这有点让我感觉像是select did back in the day,只是更糟糕的是= D

1 个答案:

答案 0 :(得分:0)

让我们对10K序列进行一些计算。最糟糕的情况是选择的ActorRef总是最后的。然后你必须进行10000+9999+...+2+1次迭代,或(10000*10001)/2 = 50 005 000。计算这个的通用公式:

Formula

我认为你不想做最坏情况的5000万次迭代:)。让我们使用不同的数据结构,看看performance characteristics of Scala collections总是好的。具有恒定移除复杂性的唯一不可变结构是HashSetHashMap。我们没有键值对,因此HashSet就足够了。由于这是在Actor中,因此可以使用可变结构,因为它保证在单个线程上运行,因此另一个选项是WeakHashMap

所以使用HashSet重写您的解决方案:

def shepherd(categories: HashSet[ActorRef]) : Receive = {
  case ForumCrawler.Done() =>
    val newCategories = categories - sender
    if(newCategories.size == 0) {
      println("all done")
      system.shutdown()
    }
    context.become(shepherd(newCategories))
}