使用 Python Timeit 為您的代碼計時
已發表: 2023-01-17在本教程中,您將學習如何使用 Python 的 timeit 模塊中的 timeit 函數。 您將學習如何在 Python 中為簡單的表達式和函數計時。
為代碼計時可以幫助您估算一段代碼的執行時間,還可以識別需要優化的代碼部分。
我們將從學習 Python 的timeit函數的語法開始。 然後我們將編寫示例以了解如何使用它來為 Python 模塊中的代碼塊和函數計時。 讓我們開始。
如何使用 Python timeit 函數
timeit模塊是 Python 標準庫的一部分,您可以導入它:
import timeit 使用timeit模塊中的timeit函數的語法如下所示:
timeit.timeit(stmt, setup, number)這裡:
-
stmt是要測量其執行時間的代碼段。 您可以將其指定為簡單的 Python 字符串或多行字符串,或傳入可調用對象的名稱。 - 顧名思義,
setup表示只需要運行一次的代碼段,通常作為stmt運行的先決條件。 例如,假設您正在計算創建 NumPy 數組的執行時間。 在這種情況下,導入numpy是setup代碼,實際創建是要計時的語句。 - 參數
number表示stmt運行的次數。number的默認值為 100 萬 (1000000),但您也可以將此參數設置為您選擇的任何其他值。
現在我們已經學習了使用timeit()函數的語法,讓我們開始編寫一些示例。
計時簡單的 Python 表達式

在本節中,我們將嘗試使用 timeit 測量簡單 Python 表達式的執行時間。
啟動 Python REPL 並運行以下代碼示例。 在這裡,我們正在計算 10000 次和 100000 次運行的求冪和底除運算的執行時間。
請注意,我們將要計時的語句作為 Python 字符串傳入,並使用分號分隔語句中的不同表達式。
>>> import timeit >>> timeit.timeit('3**4;3//4',number=10000) 0.0004020999999738706 >>> timeit.timeit('3**4;3//4',number=100000) 0.0013780000000451764在命令行運行 Python timeit
您還可以在命令行中使用timeit 。 這是 timeit 函數調用的等效命令行:
$ python-m timeit -n [number] -s [setup] [stmt]-
python -m timeit表示我們將timeit作為主模塊運行。 -
n是一個命令行選項,表示代碼應運行的次數。 這相當於timeit()函數調用中的number參數。 - 您可以使用選項
-s來定義設置代碼。
在這裡,我們使用等效的命令行重寫前面的示例:
$ python -m timeit -n 100000 '3**4;3//4' 100000 loops, best of 5: 35.8 nsec per loop 在此示例中,我們計算內置len()函數的執行時間。 字符串的初始化是使用s選項傳入的設置代碼。
$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)' 100000 loops, best of 5: 239 nsec per loop 在輸出中,請注意我們獲得了5 次運行中最好的執行時間。 這是什麼意思? 當您在命令行運行timeit時, repeat選項r被設置為默認值 5。這意味著指定number的stmt執行將重複五次,並返回最佳執行次數。
使用timeit的字符串反轉方法分析
使用 Python 字符串時,您可能希望反轉它們。 字符串反轉的兩種最常見的方法如下:
- 使用字符串切片
- 使用
reversed()函數和join()方法

使用字符串切片反轉 Python 字符串
讓我們回顧一下字符串切片的工作原理,以及如何使用它來反轉 Python 字符串。 使用語法some-string[start:stop]返回從索引start並向上延伸到索引stop-1的字符串片段。 讓我們舉個例子。
考慮以下字符串“Python”。 該字符串的長度為 6,索引列表為 0、1、2 到 5。

>>> string_1 = 'Python' 當您同時指定start和stop值時,您會得到一個從start延伸到stop-1的字符串切片。 因此, string_1[1:4]返回 'yth'。

>>> string_1 = 'Python' >>> string_1[1:4] 'yth' 當您未指定start時,將使用默認start零,切片從索引零開始,一直延伸到stop - 1 。

在這裡, stop值為 3,因此切片從索引 0 開始,一直到索引 2。
>>> string_1[:3] 'Pyt' 當您不包括stop索引時,您會看到切片從start索引 (1) 開始並一直延伸到字符串的末尾。

>>> string_1[1:] 'ython' 忽略start值和stop值將返回整個字符串的一部分。

>>> string_1[::] 'Python' 讓我們用step值創建一個切片。 將start 、 stop和step值分別設置為 1、5 和 2。 我們得到一段字符串,從 1 開始延伸到 4(不包括結束點 5),包含每隔一個字符。


>>> string_1[1:5:2] 'yh' 當您使用負步時,您可以獲得從字符串末尾開始的切片。 將步長設置為 -2, string_1[5:2:-2]給出以下切片:

>>> string_1[5:2:-2] 'nh' 因此,為了獲得字符串的反向副本,我們跳過start和stop值並將步長設置為 -1,如下所示:
>>> string_1[::-1] 'nohtyP'總之:
string[::-1]返回字符串的反向副本。
使用內置函數和字符串方法反轉字符串
Python 中的內置reversed()函數將返回字符串元素的反向迭代器。
>>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>因此,您可以使用 for 循環遍歷反向迭代器:
for char in reversed(string_1): print(char)並以相反的順序訪問字符串的元素。
# Output n o h t y P 接下來,您可以使用以下語法在反向迭代器上調用join()方法: <sep>.join(reversed(some-string)) 。
下面的代碼片段顯示了幾個示例,其中分隔符分別是連字符和空格。
>>> '-'.join(reversed(string1)) 'nohtyP' >>> ' '.join(reversed(string1)) 'nohty P'在這裡,我們不需要任何分隔符; 所以將分隔符設置為空字符串以獲取字符串的反向副本:
>>> ''.join(reversed(string1)) 'nohtyP'使用
''.join(reversed(some-string))返回字符串的反向副本。
使用 timeit 比較執行時間
到目前為止,我們已經學習了兩種反轉 Python 字符串的方法。 但是他們中哪個更快呢? 讓我們找出來。
在我們為簡單的 Python 表達式計時的先前示例中,我們沒有任何setup代碼。 在這裡,我們正在反轉 Python 字符串。 當字符串反轉操作運行 number 指定的number時, setup代碼是只運行一次的字符串的初始化。
>>> import timeit >>> timeit.timeit(stmt = 'string_1[::-1]', setup = "string_1 = 'Python'", number = 100000) 0.04951830000001678 >>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000) 0.12858760000000302 對於反轉給定字符串的相同運行次數,字符串切片方法比使用join()方法和reversed()函數更快。
使用 timeit 為 Python 函數計時

在本節中,讓我們學習如何使用 timeit 函數為 Python 函數計時。 給定一個字符串列表,以下函數hasDigit返回至少有一個數字的字符串列表。
def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit 現在我們想使用timeit測量這個 Python 函數hasDigit()的執行時間。
讓我們首先確定要計時的語句 ( stmt )。 它是對函數hasDigit()的調用,以字符串列表作為參數。 接下來,讓我們定義設置代碼。 你能猜出setup代碼應該是什麼嗎?
要成功運行函數調用,設置代碼應包括以下內容:
- 函數
hasDigit()的定義 - 字符串參數列表的初始化
讓我們在setup字符串中定義設置代碼,如下所示:
setup = """ def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit thislist=['puffin3','7frost','blue'] """ 接下來,我們可以使用timeit函數並獲取hasDigit()函數運行 100000 次的執行時間。
import timeit timeit.timeit('hasDigit(thislist)',setup=setup,number=100000) # Output 0.2810094920000097結論
您已經學習瞭如何使用Python 的 timeit 函數為表達式、函數和其他可調用對象計時。 這可以幫助您對代碼進行基準測試,比較同一函數的不同實現的執行時間,等等。
讓我們回顧一下我們在本教程中學到的內容。 您可以使用語法timeit.timeit(stmt=...,setup=...,number=...)的timeit()函數。 或者,您可以在命令行運行 timeit 來為短代碼片段計時。
下一步,您可以探索如何使用其他 Python 分析包(如 line-profiler 和 memprofiler)分別針對時間和內存分析您的代碼。
接下來,學習如何在 Python 中計算時差。
