次のようなPythonプログラムがあります。
total_error = []
for i in range(24):
error = some_function_call(parameters1, parameters2)
total_error += error
関数「some_function_call」には時間がかかり、関数の時間の複雑さを軽減する簡単な方法が見つかりません。並列タスクの実行中に実行時間を削減し、後でそれらをtotal_errorに追加する方法はありますか? poolとjoblibを使ってみましたが、どちらもうまく使えませんでした。
Python 3でconcurrent.futures
を使用することもできます。これはmultiprocessing
よりもシンプルなインターフェイスです。- これを参照 違いの詳細については。
from concurrent import futures
total_error = 0
with futures.ProcessPoolExecutor() as pool:
for error in pool.map(some_function_call, parameters1, parameters2):
total_error += error
この場合、parameters1
とparameters2
は、関数を実行する回数と同じサイズ(例では24回)のリストまたは反復可能でなければなりません。
paramters<1,2>
がiterables/mappableではなく、関数を24回実行するだけの場合は、関数のジョブを必要な回数だけ送信し、後でコールバックを使用して結果を取得できます。
class TotalError:
def __init__(self):
self.value = 0
def __call__(self, r):
self.value += r.result()
total_error = TotalError()
with futures.ProcessPoolExecutor() as pool:
for i in range(24):
future_result = pool.submit(some_function_call, parameters1, parameters2)
future_result.add_done_callback(total_error)
print(total_error.value)
python multiprocessing
を使用できます:
from multiprocessing import Pool, freeze_support, cpu_count
import os
all_args = [(parameters1, parameters2) for i in range(24)]
# call freeze_support() if in Windows
if os.name == "nt":
freeze_support()
# you can use whatever, but your machine core count is usually a good choice (although maybe not the best)
pool = Pool(cpu_count())
def wrapped_some_function_call(args):
"""
we need to wrap the call to unpack the parameters
we build before as a Tuple for being able to use pool.map
"""
sume_function_call(*args)
results = pool.map(wrapped_some_function_call, all_args)
total_error = sum(results)