この例から始めて、さまざまな使用方法を試してみたかったmultiprocessing
:
$ cat multi_bad.py
import multiprocessing as mp
from time import sleep
from random import randint
def f(l, t):
# sleep(30)
return sum(x < t for x in l)
if __name__ == '__main__':
l = [randint(1, 1000) for _ in range(25000)]
t = [randint(1, 1000) for _ in range(4)]
# sleep(15)
pool = mp.Pool(processes=4)
result = pool.starmap_async(f, [(l, x) for x in t])
print(result.get())
以下l
は、4 つのプロセスが生成されたときに 4 回コピーされるリストです。これを回避するために、ドキュメント ページでは、 を使用して作成されたキュー、共有配列、またはプロキシ オブジェクトの使用が提供されていmultiprocessing.Manager
ます。最後の 1 つについては、次の定義を変更しましたl
。
$ diff multi_bad.py multi_good.py
10c10,11
< l = [randint(1, 1000) for _ in range(25000)]
---
> man = mp.Manager()
> l = man.list([randint(1, 1000) for _ in range(25000)])
結果はまだ正しいように見えますが、実行時間が劇的に増加したため、何か間違ったことをしていると思います。
$ time python multi_bad.py
[17867, 11103, 2021, 17918]
real 0m0.247s
user 0m0.183s
sys 0m0.010s
$ time python multi_good.py
[3609, 20277, 7799, 24262]
real 0m15.108s
user 0m28.092s
sys 0m6.320s
ドキュメントには、この方法は共有配列よりも遅いと書かれていますが、これは間違っているように感じます。また、これをプロファイルして、何が起こっているかについての詳細情報を取得する方法もわかりません。何か不足していますか?
PS共有配列を使用すると、時間が0.25秒未満になります。
PPS これは Linux と Python 3.3 上にあります。