我突然意识到在功能上写起来真的不太难,所以我决定从我的代码中重构我的一些工作中删除可变集合。这个地方正在消失。现在我处于一个点,我有一个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
答案 0 :(得分:0)
让我们对10K序列进行一些计算。最糟糕的情况是选择的ActorRef总是最后的。然后你必须进行10000+9999+...+2+1
次迭代,或(10000*10001)/2 = 50 005 000
。计算这个的通用公式:
我认为你不想做最坏情况的5000万次迭代:)。让我们使用不同的数据结构,看看performance characteristics of Scala collections总是好的。具有恒定移除复杂性的唯一不可变结构是HashSet
和HashMap
。我们没有键值对,因此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))
}