2017-02-07 13 views
0

以下の一般的な例では、Fooの辞書を管理するのに、Foobar_Collectionを使用します。さらに、Foobar_Collectionは、をすべての機密で共有する方法を、Fooと順次呼びます。これまでのところうまく動作します。しかし、私は のマルチプロセッシングを利用することができて、run_myMethodForAllfoobars()はいくつかのチャンクのインスタンスを分割できますか?インスタンスメソッドはお互いに独立しています(この場合は恥ずかしそうに並行と呼ばれます)。どんな助けも素晴らしいだろう!クラスインスタンスの辞書でのマルチプロセッシング

class Foobar_Collection(dict): 
    def __init__(self, *arg, **kw): 
     super(Foobar_Collection, self).__init__(*arg,**kw) 
    def foobar(self,*arg,**kw): 
     foo = Foo(*arg,**kw) 
     self[foo.name] = foo 
     return foo 

    def run_myMethodForAllfoobars(self): 
     for name in self: 
      self[name].myMethod(10) 
     return None 


class Foo(object): 
    def __init__(self,name): 
     self.name = name 
     self.result = 0 
    # just some toy example method  
    def myMethod(self,x): 
     self.result += x 
     return None 

Foobar = Foobar_Collection() 
Foobar.foobar('A') 
Foobar.foobar('B') 
Foobar.foobar('C') 
Foobar.run_myMethodForAllfoobars() 

答えて

1

あなたはこのような状況のためmultiprocessingを使用することができますが、並列化しようとしている方法は、その副作用ではなく、その戻り値のために有用であるので、それは素晴らしいではありません。これは、Fooオブジェクトを両方向でシリアル化する必要があることを意味します(子プロセスに送信して、変更したバージョンを送り返す)。実際のオブジェクトが例のFooオブジェクトよりも複雑な場合は、各オブジェクトのデータすべてをコピーするオーバーヘッドにより、1つのプロセスですべてを行うよりも時間がかかる可能性があります。

def worker(foo): 
    foo.myMethod(10) 
    return foo 

class Foobar_Collection(dict): 
    #... 

    def run_myMethodForAllfoobars(self): 
     with multiprocessing.Pool() as pool: 
      results = pool.map(worker, self.values()) 
     self.update((foo.name, foo) for foo in results) 

より良い設計では、計算に必要な情報のみをシリアル化することができます。あなたの例では、あなたがFooオブジェクトから必要な唯一のものはあるそのresultオブジェクトの残りの部分の周りに通過することなく、あなたが抽出でき、プロセス(あなたが10を追加します):今、明らかに

def worker(num): 
    return num + 10 

class Foobar_Collection(dict): 
    #... 

    def run_myMethodForAllfoobars(self): 
     with multiprocessing.Pool() as pool: 
      results = pool.map(worker, (foo.result for foo in self.values())) 
     for foo, new_result in zip(self.values(), results): 
      foo.result = new_result 

fooオブジェクトで実際にはmyMethodが実行されることはありません(そうするのと同じですが)。このようにオブジェクトからメソッドを切り離せない場合は、良いパフォーマンスを得るのが難しいかもしれません。

+0

実際、あなたの提案のように自分の方法を切り離すことができます。ヒントと助けてくれてありがとう。私は、mpが自動的にチャンク内の辞書を「分割する」と仮定するのは正しいですか?あなたの答えに関しては、私は 'forループ'がlilエラー( 'new_result')を含んでいると思いますか?しかし、私はそれが自分のために働いて怒っています。 – Tim

+0

おっと、私は 'zip'呼び出しを省きました。これは結果を' foo'オブジェクトと一致させます。 – Blckknght

+0

それは私がそれを解決した方法です;) – Tim

関連する問題