Engineerの研鑽

メインはプログラミング系ブログ(本の要約とかもします)

質問はCONTACTやコメントでお願い致します。

【コピペでできるpython】実行速度を速くする並列処理をやってみよう

f:id:yukiyukiponsu:20190420140640j:plain

 

こんにちは、time > moneyのゆきぽんずです。

 

今日はpythonで並列処理を行っていきます。

 

並列処理を詳しく説明してくれている記事が以下になります。

(並列処理とは何か?そして並列処理と並行処理の違いとは?

https://qiita.com/4_mio_11/items/7f418ca661d9f5a2a39d

 *以下は参考記事の一部抜粋したものです。

並列処理

 

ただ、そんなに並列処理を詳しく知らなくてもいいよーという人に軽く並列処理について説明をすると、「CPUをいっぱい使って実行しようぜ!」というものになっています。

 

ちなみにCPUはこういうやつです。

詳しくはこちらのサイトを参照(CPU : https://www.pc-master.jp/words/cpu.html

*以下は参考記事の一部抜粋したものです。

CPUの説明

さてさてさーて、前置きが長くなりましたが本題に入っていきます。並列処理を実装したソースコードをどうぞ!

ソースコード

from joblib import Parallel, delayed #並列処理
import time

def process(i):
    # range(10) 10個までを実行する、つまり9個を実行
    # 要は 0,1,2,3,4,5,6,7,8の9つの数字でsumを実行
    # 後は手計算をしてみると理解できる
    # i=0を入れた時に 'id' 'sum' がどうなるかは自分で確認してほしい(理解のために)
    return [{'id': j, 'sum': sum(range(i*j))} for j in range(10)]

#通常の処理で実行
result = [0]*10
start = time.time()
for i in range(0, 10):
     result = process(i)
end = time.time()

start_paralell = time.time() #測定開始
#並列処理で実行
result_paralell = Parallel(n_jobs=-1)([delayed(process)(n) for n in range(10)])
end_paralell = time.time()

print("result :", result)
print("通常処理にかかった時間 :", end - start)
print("result_paralell :", result_paralell)
print("平行処理にかかった時間 :", end_paralell - start_paralell)

本来マルチでプロセッサを使っている並列処理の方が速いはずなので、それを確かめるために同様の処理を普通のfor文でも実装してみました。

 

結果発表ーーーーーーーーーーーーーーーーーー(〇田風 : 某芸人さん)

実行結果

実行結果

見ずらいですよね。すいません。注目してほしいのは実行速度と最後の実行結果です。

拡大します。

通常処理実行結果

通常実行結果

並列処理実行結果

ぼかしの部分は見てほしい部分ではないので消しました。自分不器用なので下の部分まで消えかかっているのはご容赦ください。

並列処理実行結果

見比べてもらうとわかるように実行結果は一緒です。「あれっ?さっき並列処理の方が実行速度速くなるって言わなかったけ?」と思った方、流石です。

その通り!見てもらうとわかるように並列処理の方が実行速度が遅いんです。ちょっと説明しますね。

 

通常処理は以下の図のように1が終わってから2を実行..最後に9を実行といったように続いていきますが、並列処理では1~9までを同時に実行していき並列的に1~9を最後まで処理します。並列処理は1~9を同時に処理ができる代わりに結果に齟齬が生じないようにしなければいけません。本来は1~9と順番に行う処理を、無理くり同時に処理しているので結果の整合性を保つためにどうしても内部で余計な処理を挟まないといけません。結果としてその処理によって実行時間が遅れているのです。

通常処理と並列処理

 

「だったら並列化する必要ないじゃん」と思われた方もいると思いますが、それはナンセンスでーす。その欠点を克服するほど実行速度が速いのです!!!!

 

嘘だと思いますか?では証拠を見せましょう!先ほどのソースコードのfor文を回す回数を増やしていきましょう(for i in range(ここを増やす))!もちろん並列処理の方も増やしてくださいね(for n in range(ここを増やす))。

 

ではではいきます。今回は実行時間だけを知りたいので実行時間だけ表示しています。

とりあえずforを1000回まわした時

1000回実行

なんのなんの10000回

10000回実行

おっいいかんじ、界王拳100000べえだーーーーーーーーーーーー

100000回実行

v( ̄Д ̄)v イエイ。並列処理の方が速くなりましたね。もっと回す回数を増やせば増やすほど並列処理の方が速くなります。あとは自分で試してみてね!

 

今日は以上になります。

 

今日もブログを読んでくださりありがとうございます。

 

それではまた明日ーーー。