檢視執行時間

撰寫高效的 Python 程式碼

Logan Thomas

Scientific Software Technical Trainer, Enthought

為什麼要量測程式時間?

  • 幫助我們選出最佳寫法
  • 程式越快=效率越高!
撰寫高效的 Python 程式碼

如何量測程式時間?

  • 用 IPython 的 magic 指令 %timeit 計算執行時間

  • Magic 指令:對一般 Python 語法的加強

    • 以「%」字元作為前綴
    • 文件連結(here
    • %lsmagic 查看所有可用的 magic 指令
撰寫高效的 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="magic 指令 timeit 的輸出"

撰寫高效的 Python 程式碼

%timeit 輸出

alt="magic 指令 timeit 的輸出,標示平均值與標準差"

撰寫高效的 Python 程式碼

%timeit 輸出

alt="magic 指令 timeit 的輸出,標示執行次數與每次迴圈數"

撰寫高效的 Python 程式碼

指定 runs/loops 數量

設定執行次數(-r)與/或每次迴圈數(-n

# 將執行次數設為 2(-r2)
# 將每次迴圈數設為 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

行內 magic(%timeit

# 單行程式碼

%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

儲存格 magic(%%timeit

# 多行程式碼

%%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...