【Python】並列処理とfor文
並列処理とは?
Pythonで大量のデータを処理する際、通常のfor文を使うと逐次実行になり、処理時間が長くなることがあります。並列処理を活用することで、複数の処理を同時に実行し、効率的にタスクを完了させることができます。
threadingを使った並列処理
Pythonの標準ライブラリであるthreading
モジュールを使うと、マルチスレッドを用いた並列処理が可能になります。ただし、PythonのGIL(Global Interpreter Lock)の影響により、CPUバウンドな処理ではあまり効果が得られません。
threadingを使った基本的な例
import threading
def print_number(num):
print(f"Thread {num} is running")
threads = []
for i in range(5):
thread = threading.Thread(target=print_number, args=(i,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
このコードでは、5つのスレッドを作成し、それぞれが異なる番号を出力します。ただし、CPUを多く使用する処理(数値計算など)には適していません。
multiprocessingを使った並列処理
multiprocessing
モジュールを使用すると、PythonのGILの制約を回避し、複数のプロセスで処理を並列化できます。CPUバウンドなタスクに適しています。
multiprocessingを使った基本的な例
import multiprocessing
def square(num):
return num * num
if __name__ == "__main__":
with multiprocessing.Pool(processes=4) as pool:
results = pool.map(square, range(10))
print(results)
この例では、4つのプロセスを使ってリスト内の数値の二乗を計算しています。CPUバウンドな処理では、multiprocessing
を使うことで大幅に高速化できます。
concurrent.futuresを使った並列処理
concurrent.futures
モジュールを使うと、スレッドとプロセスの両方を簡単に管理できます。スレッドプールとプロセスプールのどちらを使うかを選べる点が特徴です。
ThreadPoolExecutorを使った例
from concurrent.futures import ThreadPoolExecutor
def fetch_data(num):
print(f"Fetching data {num}")
return num * 2
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(fetch_data, range(10)))
print(results)
ProcessPoolExecutorを使った例
from concurrent.futures import ProcessPoolExecutor
def compute_square(num):
return num * num
with ProcessPoolExecutor(max_workers=4) as executor:
results = list(executor.map(compute_square, range(10)))
print(results)
ThreadPoolExecutor
はI/Oバウンドなタスクに適し、ProcessPoolExecutor
はCPUバウンドなタスクに適しています。
各手法の比較
手法 | 特徴 | 適した処理 |
---|---|---|
threading | 軽量だがGILの影響を受ける | I/Oバウンド(ネットワーク通信、ファイル操作) |
multiprocessing | プロセス単位で並列処理可能 | CPUバウンド(数値計算、大量データ処理) |
concurrent.futures | スレッドとプロセスを簡単に扱える | 汎用的(処理内容に応じて使い分け) |
まとめ
Pythonで並列処理を実装する方法として、threading
、multiprocessing
、concurrent.futures
の3つがあり、それぞれ適した用途が異なります。用途に応じて最適な手法を選ぶことで、処理の効率を大幅に向上させることができます。