は、このプログラム例を取る:なぜ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
に頼るのではなく、データを自分でチャンクする必要がありますか?