
Pythonである程度重い処理をしなければいけない時に、コードの効率を改善することがあります。改善は定量的に評価してこそ有効な効果を出す案に辿り着くことができます。ここではPythonのtime関数を使ってプログラムの処理時間を計測する方法を紹介します。
こんにちは。wat(@watlablog)です。
Pythonプログラミングの基本!経過時間を計測する方法を説明します!
目次(項目クリックでジャンプできます)
プログラム実行速度タイムアタックで効率改善しよう!
処理時間を計測するとアルゴリズムの比較ができる
「プログラムは動けば良い」と思っている人は少なからずいらっしゃると思いますが、その考えは最後の最後で自分の首をしめることになりかねません。
例えばcsvに保存された時刻歴波形を解析するプログラムを作って誰かに配布したとします。そのプログラムを作っている段階では1sや2sのデータで計算を検証していたとしても、ユーザによっては1分、10分のデータを解析したいというケースも出てくるでしょう。
1sのデータの解析に1sかかっていたとしたら、10分のデータは600sかかってしまいます。計算時間問題が技術的にハードルが高いものであればある程度仕方が無い部分もありますが、プログラマの怠慢で遅くなっているとしたら非常にもったいないですよね。
ユーザの数だけ使い方があるように、一人の開発者が全ケースを予め想定しておくことはできません。そのため、プログラムは出来る限りシンプルに、高速に動くようにしておく必要があります。
ある関数で、forループで書ける所をwhileループで書いていたとしたら?
どちらのアルゴリズムが効率が良いのかを正しく知るためには計測による定量評価が必要です。
Pythonでプログラム処理時間を計測するコード
ここではプログラムの処理時間を計測するコードを使って、配列の演算(X * Y)をforループ、whileループ、numpyの配列演算の3つのパターンで比較する例を示します。
配列の演算で処理時間を比較してみる
forループの場合
まずはループ計算の代表格であるforループから検証用コードを紹介します。
時間計測用のコードは、import timeでtimeパッケージ(Pythonインストール時から入っている)をインポートし、time.time()で現在時間を取得する部分です。
t0として主要のコードが始まる前の時刻を取得し、t1としてコードの最後に再度時刻取得を行います。その後、t1 - t0をすることで簡単に処理時間を算出することができます。
forループの処理ですが、ちょっとPythonをやったことがある人はこんなコードは書かないと思います。今回は時間計測のためのデモとしてあえて書いているので、その辺ご了承下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import numpy as np import time t0 = time.time() # 計測開始時間を取得 # ここから処理 a = 0.001 x = np.arange(0, 100, a) y = np.arange(0, 100, a) # forループを使ってxとyを乗算 z = [] for i in range(len(x)): z.append(x[i] * y[i]) # ここまで処理 t1 = time.time() # 計測終了時間 elapsed_time = float(t1 - t0) # 経過時間 print(elapsed_time) # 経過時間を表示 |
whileループ
次はwhileループで同じ結果を得る処理を書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import numpy as np import time t0 = time.time() # 計測開始時間を取得 # ここから処理 a = 0.001 x = np.arange(0, 100, a) y = np.arange(0, 100, a) # whileループを使ってxとyを乗算 z = [] i = 0 while i < len(x): z.append(x[i] * y[i]) i = i + 1 # ここまで処理 t1 = time.time() # 計測終了時間 elapsed_time = float(t1 - t0) # 経過時間 print(elapsed_time) # 経過時間を表示 |
numpy配列演算
最後にnumpyに備わっている配列演算の場合です。おそらく多くの人はこの方法で書くでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import numpy as np import time t0 = time.time() # 計測開始時間を取得 # ここから処理 a = 0.001 x = np.arange(0, 100, a) y = np.arange(0, 100, a) # numpyの行列演算を使ってxとyを乗算 z = x * y # ここまで処理 t1 = time.time() # 計測終了時間 elapsed_time = t1 - t0 # 経過時間 print(elapsed_time) # 経過時間を表示 |
各アルゴリズムの平均処理時間(n=100)
以下は上の3つのアルゴリズムパターンの処理時間計測比較結果です。
PCといっても演算ばらつきはあるので、試行回数100回の結果を平均しています。
これを見るとforループよりwhileループの方が36%ほど悪く、forループよりもnumpyの方が96%ほど良い結果を示していることがわかります。
numpyの配列演算で計算を行えるプログラムを、forループやwhileループで書くことは相当効率の悪いことだとわかりますね。

まとめ
メインはプログラムの処理時間計測の方法ですが、各アルゴリズムで差がこんなにも明確に出たことが驚きですね。
処理時間計測自体はPythonに標準で備わっている方法で簡単に行うことができます。
是非、自分の書いたプログラムがもっとはやくなるかどうかという視点もコーディング時に持つきっかけにして頂けたら幸いです。
今回の方法で様々な処理を計測することが可能になりました!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!