概要
マルチプロセス、簡単にやりましょう。
でも、ちょっとやり方に詰まって結局時間節約できなかった。。??
もぅマヂ無理。。。。。普通にfor文まわそ。。。。
そういう人に読んでもらいたい。
Pythonの標準装備であるProcessPoolExecutorとfunctools.partial をつかって、快適にマルチプロセスで並列計算しましょう。
使えるものは、使わないと損だよね??
状況説明
def my_function(arg1):
for i in range(100):
'めっちゃヘビーな処理ですのん'
result_list.append(some_operation(i))
if __name__ == "__main__":
my_function()
こういう書き方、けっこう何も考えずに書きますよね?
こういうとき、100回の処理あるけど、マルチプロセスで簡単に並列処理したい。。。
簡単なやり方
- 関数をちょろっと書き直します。
- ProcessPoolExecutor をインポート。
- functools.partial をインポートし関数をマッピング。
1. 関数をちょろっと書き直します。
先ほどの my_function
を、こんな風に書きます。
def my_function(index, arg1):
return some_operation(index)
つまり、ループを書くんじゃなくて、インデックスを渡して、一個一個処理するみたいなイメージ。
2. ProcessPoolExecutor をインポート。
まず、以下のように書きます。
import os
from concurrent.futures import ProcessPoolExecutor
max_workers = os.cpu_count() or 4
print('=====MAX WORKER========')
print(max_workers)
with ProcessPoolExecutor(max_workers=max_workers) as executor:
max_workers
は、使用可能なプロセス数が格納されます。もし格納できない場合、この例では4
が入ります。
3. functools.partial をインポートし関数をマッピング。
つづいて、こんな風に書きます。
import functools
with ProcessPoolExecutor(max_workers=max_workers) as executor:
result_list = list(executor.map(functools.partial(my_function, arg1), range(100)))
executor.shutdown(wait=True)
これだけです。
少し解説すると、今までループで書いて、result_list
にアペンドしていた操作は、
my_funtion
にインデックスを渡すことで、各インデックスでのオペレーションを複数プロセスに分けて実行するため。
functools.partial
は、関数(my_function)の一部の引数を変えて、引数の変わったそれぞれの関数を関数のイテレータとして返します。このとき、my_function(index, arg1)
のように、変更される引数は1つであり、それが関数の第一引数となっていることに注意!!
さらに、executor.mapにより、そのmy_function
に渡される第一変数であるindexは、イテレータであるrange(100)のそれぞれで並列実行され、各実行結果がlistに格納されます。
これはまさに、result_list
に各ループでアペンドしていた時と一緒です。
簡単なexampleコードはこちら
from concurrent.futures import ProcessPoolExecutor
import functools
def test(arg1, index):
print(f"index: {index}")
return index + arg1
if __name__ == "__main__":
arg1 = 1
with ProcessPoolExecutor(max_workers=4) as executor:
result = list(executor.map(functools.partial(test, arg1), range(10)))
# result = list(executor.map(test, range(10)))
print(list(result))
まとめ
少しでも時間を節約するためにやりたいマルチプロセス。マルチプロセスの書き方で苦労して結局時間めっちゃかかった、、みたいなことになるの、辛いですよね。。。
今回は自分的にかなり簡単にPythonの標準ライブラリだけをつかって書けるマルチプロセスについて紹介させていただきました!!
おわり。