使用 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 中計算時差。