実行時間の調査

効率的なPythonコードの書き方

Logan Thomas

Scientific Software Technical Trainer, Enthought

なぜコードの実行時間を計測するのか?

  • 最適なコーディング手法を選択できる
  • 高速なコード == 効率的なコード!
効率的なPythonコードの書き方

コードの実行時間を計測するには?

  • IPythonマジックコマンド %timeit で実行時間を計測する

  • マジックコマンド: 通常のPython構文を拡張する機能

    • 「%」文字がプレフィックス
    • ドキュメントはこちら(リンク
    • 利用可能なコマンド一覧は %lsmagic で確認
効率的なPythonコードの書き方

%timeit の使い方

計測するコード

import numpy as np

rand_nums = np.random.rand(1000)

%timeit による計測

%timeit rand_nums = np.random.rand(1000)
8.61 µs ± 69.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
効率的なPythonコードの書き方

%timeit の出力

alt="%timeit マジックコマンドの出力"

効率的なPythonコードの書き方

%timeit の出力

alt="平均値と標準偏差が強調表示された%timeit出力"

効率的なPythonコードの書き方

%timeit の出力

alt="実行回数とループ回数が強調表示された%timeit出力"

効率的なPythonコードの書き方

実行回数/ループ回数の指定

実行回数(-r)とループ回数(-n)の指定

# Set number of runs to 2 (-r2)
# Set number of loops to 10 (-n10)

%timeit -r2 -n10 rand_nums = np.random.rand(1000)
16.9 µs ± 5.14 µs per loop (mean ± std. dev. of 2 runs, 10 loops each)
効率的なPythonコードの書き方

ラインマジックモードでの %timeit 使用

ラインマジック(%timeit

# Single line of code

%timeit nums = [x for x in range(10)]
914 ns ± 7.33 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
効率的なPythonコードの書き方

セルマジックモードでの %timeit 使用

セルマジック(%%timeit

# Multiple lines of code

%%timeit
nums = []
for x in range(10):
    nums.append(x)
1.17 µs ± 3.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
効率的なPythonコードの書き方

出力の保存

出力を変数に保存する(-o

times = %timeit -o rand_nums = np.random.rand(1000)
8.69 µs ± 91.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
効率的なPythonコードの書き方
times.timings
[8.697893059998023e-06,
 8.651204760008113e-06,
 8.634270530001232e-06,
 8.66847825998775e-06,
 8.619398139999247e-06,
 8.902550710008654e-06,
 8.633500570012985e-06]
times.best
8.619398139999247e-06
times.worst
8.902550710008654e-06
効率的なPythonコードの書き方

実行時間の比較

Pythonのデータ構造は正式名称で作成できる

formal_list = list()
formal_dict = dict()
formal_tuple = tuple()

Pythonのデータ構造はリテラル構文でも作成できる

literal_list = []
literal_dict = {}
literal_tuple = ()
効率的なPythonコードの書き方
f_time = %timeit -o formal_dict = dict()
145 ns ± 1.5 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
l_time = %timeit -o literal_dict = {}
93.3 ns ± 1.88 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
diff = (f_time.average - l_time.average) * (10**9)
print('l_time better than f_time by {} ns'.format(diff))
l_time better than f_time by 51.90819192857814 ns
効率的なPythonコードの書き方

実行時間の比較

%timeit formal_dict = dict()
145 ns ± 1.5 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit literal_dict = {}
93.3 ns ± 1.88 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
効率的なPythonコードの書き方

さあ、始めましょう!

効率的なPythonコードの書き方

Preparing Video For Download...