2017-03-01 6 views
0

は、このプログラム例を取る:なぜPython ThreadPoolExecutor.mapは、ProcessPpplExecutorと比較して、結果が出るまでに時間がかかりますか?

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor 

def fun(xx): 
    for _ in range(10): 
     y = 1 
     x = xx 
     while x > 0: 
      y = (y * x) % 1000000007 
      x -= 1 
    print("END {}! = {}".format(xx, y)) 
    return xx, y 

with ThreadPoolExecutor(max_workers=8) as executor: 
    out = executor.map(fun, range(10000)) 
    for x in out: 
     print(x) 

これは私は、関数が実際に計算されるたびに印刷されたメッセージを確認し、また、出力は、出力発電機に読み込まれてからすることができます。機能メッセージは厳密には順序通りではなく、ジェネレータは順調である必要があります。また、私はジェネレータがデータを「パイプラインとして」提供し、入力全体が処理される前に中間結果を得ることを期待しています。これは、私が処理している無限のストリームである可能性があります。

ProcessPoolExecutorを使用すると、これは期待どおりに動作し、新しい結果がスレッドプールによって作成されている間にすぐに出力ジェネレータからの読み取りを開始できます。一方、ThreadPoolExecutorでは、うまく動作しているように見えますが、多くの関数がすでに実行された後は、出力を提供し始めるだけです。たとえば:

END 6363! = 280520285 
END 6364! = 231081245 
END 6365! = 832114135 
END 6366! = 238546331 
(0, 1) 
(1, 1) 
(2, 2) 
(3, 6) 
(4, 24) 
END 6368! = 281286418 
END 6369! = 513183705 
END 6370! = 980177974 

なぜこのような大きな違いがありますか?この動作を制御するにはどうすればよいですか。スレッドを使用したい場合、結果がより速くなることを確認したいのですが、mapに頼るのではなく、データを自分でチャンクする必要がありますか?

答えて

0

ProcessPoolExecutorの結果がより速くなる理由の1つは、イテレータのチャンクを作成することで、各チャンクがCPUのコア(割り当てた作業者の数)にarsinesし、そのコアがそのチャンクの計算を速く完了し、さらにforループを実行してください

関連する問題