使用 Python 的 timeit 模塊測量處理時間。

商業

使用 Python 標準庫的 timeit 模塊,您可以輕鬆測量代碼中進程的執行時間。這對於快速檢查很有用。

這裡將討論以下兩種情況。

  • 在 Python 文件中測量:timeit.timeit(),timeit.repeat()
  • 使用 Jupyter Notebook 進行測量:%timeit,%%timeit

另一種方法是使用 time.time() 來測量程序中經過的時間。

Python 文件中的測量:timeit.timeit()、timeit.repeat()

例如,我們將測量一個簡單函數 test(n) 的處理時間,該函數計算 n 個連續數字的總和。

import timeit

def test(n):
    return sum(range(n))

n = 10000
loop = 1000

result = timeit.timeit('test(n)', globals=globals(), number=loop)
print(result / loop)
# 0.0002666301020071842

如果您將要測量的代碼作為字符串傳遞給 timeit.timeit() 函數,它將被執行 NUMBER 次並返回其花費的時間。
數字的默認值為 1,000,000。請注意,如果對耗時的過程使用默認值,則會花費大量時間。

通過將 globals() 作為參數 globals 傳遞,代碼將在全局命名空間中執行。
如果沒有這個,函數 test 和變量 n 在上面的例子中就無法識別。

要指定的代碼可以是可調用對象而不是字符串,因此可以指定為不帶參數的 lambda 表達式;在這種情況下,不需要指定參數 globals。

result = timeit.timeit(lambda: test(n), number=loop)
print(result / loop)
# 0.00027574066299712287

結果的單位是秒。這裡,輸出是每次執行的處理時間除以執行次數。

如果不進行除法,結果值會隨著執行次數的增加而變得更大。

print(timeit.timeit(lambda: test(n), number=1))
print(timeit.timeit(lambda: test(n), number=10))
print(timeit.timeit(lambda: test(n), number=100))
# 0.0003999490290880203
# 0.0038685189792886376
# 0.03517670702422038

使用 timeit.repeat() 函數,可以重複執行 timeit()。結果將作為列表獲得。

repeat = 5
print(timeit.repeat(lambda: test(n), repeat=repeat, number=100))
# [0.044914519996382296, 0.039663890027441084, 0.02868645201670006, 0.022745631984435022, 0.023260265996214002]

使用 Jupyter Notebook 進行測量:%timeit, %%timeit

在 Jupyter Notebook (IPython) 中,您可以使用以下魔術命令;無需導入 timeit 模塊。

  • %timeit
  • %%timeit

%timeit

在 %timeit 中,指定由空格分隔的目標代碼,如命令行參數。

默認情況下,timeit.timeit() 中的次數和重複次數是自動確定的。您還可以使用 -n 和 -r 選項指定它們。

結果計算為平均值和標準偏差。

%timeit test(n)
# 259 µs ± 4.87 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit -r 3 -n 10000 test(n)
# 237 µs ± 6.44 µs per loop (mean ± std. dev. of 3 runs, 10000 loops each)

%%時間

魔術命令 %%timeit 可用於測量整個單元格的處理時間。

例如,讓我們使用 NumPy 運行相同的過程。 -n 和 -r 選項可以省略。

由於我們測量的是整個單元格的處理時間,因此下面的示例包括導入 NumPy 的時間。

%%timeit -r 3 -n 10000
import numpy as np
a = np.arange(n)
np.sum(a)
# 19.7 µs ± 9.57 µs per loop (mean ± std. dev. of 3 runs, 10000 loops each)

無需將目標代碼指定為 %%timeit 的參數。您所要做的就是在單元格的開頭寫入 %%timeit,因此它最容易使用。