前回からの続きです。
pool
python で mulitprocessing を行う方法として、process 以外に pool があります。
process と pool の違い
Python Multiprocessing: Pool vs Process – Comparative Analysis
process は、複数の関数を複数プロセスで並列して実行します。実行中の関数は全てメモリ上に展開されます。
pool では、一つの関数に複数の処理を行わせる際に、その処理を複数プロセスに割り当てて並列して実行します。pool 側でタスクの分割や結果の統合といったことを暗黙的に制御し、実行中の処理のみがメモリ上に展開されます。
pool を使ってみる
0から与えられた数字までのそれぞれの数を3乗して、それらの和を取る関数を考えます。
この関数を、0からある数まで実行して、それぞれの結果をリストにして返す関数を考えます。
multiprocessing は使わず、普通に実行してみます。
import time
def sum_cube(num):
s = 0
for i in range(num):
s += i * i * i
return s
def return_list_sum_cube(numbers):
start = time.time()
result = []
for i in numbers:
result.append(sum_cube(i))
end = time.time() - start
print(f'No Multiprocessing: {end} seocnds')
if __name__ == '__main__':
numbers = range(10)
# sum_square_with_mp(numbers)
results = return_list_sum_cube(numbers)
print(results)
# 実行結果
# No Multiprocessing: 0.0 seocnds
# [0, 0, 1, 9, 36, 100, 225, 441, 784, 1296]
上の処理を、multiprocessing.Pool() を使って書いてみます。
import time
import multiprocessing
def sum_cube(num):
s = 0
for i in range(num):
s += i * i * i
return s
def return_list_sum_cube_with_multiprocessing(numbers):
start = time.time()
p = multiprocessing.Pool()
result = p.map(sum_cube, numbers)
p.close()
p.join()
end = time.time() - start
print(f'Multiprocessing: {end} seocnds')
return result
if __name__ == '__main__':
numbers = range(10)
result = return_list_sum_cube_with_multiprocessing(numbers)
print(result)
# 実行結果
# Multiprocessing: 0.3670167922973633 seocnds
# [0, 0, 1, 9, 36, 100, 225, 441, 784, 1296]
mulitprocessing を使った方が時間がかかってしまいました。
このループ回数では、multiprocessing は使わずに、普通に処理した方が速いようです。
ループを増やしてみます。
| loop | 10 | 100 | 1000 | 3000 | 5000 | 10000 |
| serial | 0 | 0.001 | 0.0558 | 0.6043 | 1.5538 | 8.2210 |
| multi | 0.367 | 0.3909 | 0.3650 | 0.6013 | 1.0122 | 2.6110 |
私の pc では、大体ループが5000回を超えるあたりで、multprocessing を使った方が処理が速く終わるようでした。