0

機能的に書くのはそれほど難しくないことに気がついたので、自分の作業の一部をリファクタリングして、コードから変更可能なコレクションを削除することにしました。ロックはただ溶けてしまいます。これで、監視対象のアクターのコレクションを表す Seq ができました。1 つ完了するたびに、シーケンスからそれを削除する必要があります。機能的には、新しい seq を作成し、新しいシーケンスで akka bell を実行すると思います。

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 はどういうわけか舞台裏でシーケンスを変更するのでしょうか、それとも完全なセットから set copy を取得するのでしょうか?

これは、 select が当時行っていたような気がしますが、おそらくもっと悪い = D

4

1 に答える 1

0

10K シーケンスの計算をしてみましょう。最悪のシナリオは、選択された ActorRef が常に最後である場合です。次に10000+9999+...+2+1、反復を行う必要があります(10000*10001)/2 = 50 005 000。これを計算するための一般式:

方式

最悪の場合の5000万回の反復を実行したいとは思わない:)。別のデータ構造を使用してみましょう。Scalaコレクションのパフォーマンス特性を確認することは常に良いことです。一定の削除の複雑さを持つ唯一の不変の構造はHashSetandHashMapです。キーと値のペアがないので、これHashSetで十分です。これはアクタ内にあるため、単一のスレッドで実行されることが保証されているため、変更可能な構造を潜在的に使用できます。したがって、他のオプションは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))
}
于 2013-11-13T11:34:18.720 に答える