プログラムの処理時間
前回、Pythonで各変数が使用しているメモリの状況を取得する方法を紹介しました。
プログラムがどれだけパソコンに負荷をかけているかに関して、確かにメモリ(やCPU)の使用量を確認するのは一つの良い手だと思います。
ただもう一つ、実際に処理にかかる時間を測定するというのも、プログラムのパソコンへの負荷を確認するのに良い手だと考えられます。
ということで今回は、プログラムの処理時間を確認する方法を試していきましょう。
timeモジュールを使った方法
まずはPythonプログラムで使える「timeモジュール」を使った方法を紹介します。
timeモジュールはdatetimeモジュールと同じく「時間」を扱うモジュールですが、datetimeモジュールは年月日や時刻を扱うのが得意なのに対し、timeはプログラムを一時停止させたり、エポック秒を取得するモジュールです。
エポック秒に関してはこちらの記事をご覧ください。
そしてこのtimeモジュールを使って、処理時間を測る方法としては、単純に処理前後のエポック秒を取得し、引き算することで処理に何秒かかったかを確認するというやり方です。
ということでプログラムはこんな感じです。
import time
time_start = time.time()
cycle = 10000000
x = [i*i for i in range(cycle)]
time_end = time.time()
time_process = time_end - time_start
print(time_process)
実行結果
1.8686408996582031
最初に「time_start = time.time()」で現在のエポック秒を取得します。
そして何らかの処理をします。
今回はリスト内包表記を使って、二乗を計算し、リストに格納してみました(x = [i*i for i in range(cycle)])。
次に処理後の時間を取得します(time_end = time.time())。
そして処理後の時間から処理前の時間を引き算し、処理時間を取得します(time_process = time_end – time_start)。
処理前、処理後の時間を取得して、引き算するという性質上、ちょっと手間がかかってしまいます。
Pythonの実行形式プログラムならこの方法しかない(?)ように思えますが、Jupyter Notebookを使用している場合はマジックコマンドで処理時間を測ることができます。
Jupyter Notebookのマジックコマンドでプログラムの処理時間を計測
プログラムの処理時間を計測するマジックコマンドは「time」と「timeit」の2種類があります。
timeでは実行し、それにかかった時間を表示してくれます。
timeitでは”複数回”実行し、それにかかった時間と標準偏差を表示してくれます。
どちらも「%」を頭につけると、その行でかかった時間を、「%%」を頭につけ、セルの最初に置くと、そのセルでかかった時間を表示してくれます。
%time
cycle = 10000000
%time x = [i*i for i in range(cycle)]
実行結果
CPU times: user 1.3 s, sys: 657 ms, total: 1.96 s
Wall time: 2.53 s
%%time
%%time
cycle = 10000000
x = [i*i for i in range(cycle)]
実行結果
CPU times: user 1.24 s, sys: 254 ms, total: 1.49 s
Wall time: 1.8 s
%timeit
cycle = 10000000
%timeit x = [i*i for i in range(cycle)]
実行結果
1.58 s ± 53.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
%%timeit
cycle = 10000000
x = [i*i for i in range(cycle)]
実行結果
1.53 s ± 65.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
ちなみにマジックコマンドをつけた状態でPython実行形式ファイル(.pyファイル)を実行してみたのですが、マジックコマンドがある行は処理されず、無視されているようでした。
Jupyter Notebookでプログラムを作成し、実際に使用するのは.py ファイルという方はお気をつけください。
自己関数はどこで処理されるのか?
こう時間を測れるようになって気になったのは、自己関数を使用している場合、どこで時間を測定したらいいかということでした。
つまり、こんな感じでセル1に自己関数、セル2で実行といった場合、どこにセルの実行時間を計測する「%%time」やら「%%timeit」を置いたらいいのかということです。
<セル1>
def test(cycle):
x = [i*i for i in range(cycle)]
return x
<セル2>
cycle = 10000000
test(cycle)
ということでそれぞれのセルに「%%time」を追加し、実行してみました。
<セル1>
%%time
def test(cycle):
x = [i*i for i in range(cycle)]
return x
実行結果
CPU times: user 7 µs, sys: 2 µs, total: 9 µs
Wall time: 14.8 µs
<セル2>
%%time
cycle = 10000000
test(cycle)
実行結果
CPU times: user 1.05 s, sys: 179 ms, total: 1.23 s
Wall time: 1.64 s
当然の結果ではあるのですが、セル1の処理は7μ秒と即座に終わるのに対し、セル2の処理は1.05秒を時間がかかりました。
確かにセル1では自己関数の「読み込み」だけなので即座に終わるというわけです。
次回はやっと本題、matplotlibでのメモリリークの話をしていきます。
ではでは今回はこんな感じで。
コメント