Python timeit模塊的使用實(shí)踐
Python 中的 timeit 模塊可以用來測(cè)試一段代碼的執(zhí)行耗時(shí),如一個(gè)變量賦值語句的執(zhí)行時(shí)間,一個(gè)函數(shù)的運(yùn)行時(shí)間等。
timeit 模塊是 Python 標(biāo)準(zhǔn)庫中的模塊,無需安裝,直接導(dǎo)入就可以使用。導(dǎo)入時(shí)直接 import timeit ,可以使用 timeit() 函數(shù)和 repeat() 函數(shù),還有 Timer 類。使用 from timeit import ... 時(shí),只能導(dǎo)入 Timer 類(有全局變量 __all__ 限制)。
timeit 模塊的源碼總共只有 300 多行,主要就是實(shí)現(xiàn)上面的兩個(gè)函數(shù)和一個(gè)類,可以自己看一下。
接下來就開始使用 timeit 模塊來測(cè)試代碼執(zhí)行時(shí)間,我使用 timeit 模塊來對(duì)比 Python 列表從頭部添加數(shù)據(jù)和從尾部添加數(shù)據(jù)的執(zhí)行時(shí)間(測(cè)試什么根據(jù)需求來定)。
一、使用 timeit() 函數(shù)測(cè)試運(yùn)行時(shí)間
1. 準(zhǔn)備測(cè)試函數(shù)
先寫兩個(gè)函數(shù),一個(gè)函數(shù)是從列表頭部添加數(shù)據(jù),另一個(gè)函數(shù)是從列表尾部添加數(shù)據(jù)。
# coding=utf-8 def insert_time_test(): insert_list = list() for i in range(10): insert_list.insert(0, i) def append_time_test(): append_list = list() for i in range(10): append_list.append(i) if __name__ == '__main__': import timeit
2. timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number) 函數(shù)介紹
timeit() 函數(shù)有四個(gè)參數(shù),每個(gè)參數(shù)都是關(guān)鍵字參數(shù),都有默認(rèn)值。
stmt:傳入需要測(cè)試時(shí)間的代碼,可以直接傳入代碼表達(dá)式或單個(gè)變量,也可以傳入函數(shù)。傳入函數(shù)時(shí)要在函數(shù)名后面加上小括號(hào),讓函數(shù)執(zhí)行,如 stmt = ‘func()' 。
setup:傳入 stmt 的運(yùn)行環(huán)境,如 stmt 中使用到的參數(shù)、變量,要導(dǎo)入的模塊等,如 setup = ‘from __main__ import func'??梢詫懸恍姓Z句,也可以寫多行語句,寫多行語句時(shí)用分號(hào)隔開。
如果 stmt 和參數(shù) setup 參數(shù)不傳值,那么就失去了測(cè)試的意義,所以這兩個(gè)參數(shù)是必要的。
timer: timer 參數(shù)是當(dāng)前操作系統(tǒng)的基本時(shí)間單位,默認(rèn)會(huì)根據(jù)當(dāng)前運(yùn)行環(huán)境的操作系統(tǒng)自動(dòng)獲取(源碼中已經(jīng)定義),保持默認(rèn)即可。
number:要測(cè)試的代碼的運(yùn)行次數(shù),默認(rèn)1000000(一百萬)次,對(duì)于耗時(shí)的代碼,運(yùn)行太多次會(huì)花很多時(shí)間,可以自己修改運(yùn)行次數(shù)。
3. 測(cè)試函數(shù)的運(yùn)行時(shí)間
現(xiàn)在使用 timeit() 來測(cè)試上面兩個(gè)函數(shù)的運(yùn)行時(shí)間。
insert_time_timeit = timeit.timeit(stmt='insert_time_test()', setup='from __main__ import insert_time_test') print('insert_time_timeit: ', insert_time_timeit) append_time_timeit = timeit.timeit(stmt='append_time_test()', setup='from __main__ import append_time_test') print('append_time_timeit: ', append_time_timeit)
運(yùn)行結(jié)果:
('insert_time_timeit: ', 2.9112871)
('append_time_timeit: ', 1.8884124999999998)
可以看到,在列表頭部添加數(shù)據(jù)的時(shí)間比在列表尾部添加數(shù)據(jù)的時(shí)間長(zhǎng)。
4. 測(cè)試代碼(表達(dá)式)的運(yùn)行時(shí)間
繼續(xù)使用 timeit() 測(cè)試上面代碼的運(yùn)行時(shí)間,只是這次是直接將代碼傳入到參數(shù)中,而不是傳入函數(shù)。
insert_time_timeit = timeit.timeit(stmt='list(insert_list.insert(0, i) for i in init_list)', setup='insert_list=list();init_list=range(10)', number=100000) print('insert_time_timeit: ', insert_time_timeit) append_time_timeit = timeit.timeit(stmt='list(append_list.append(i) for i in init_list)', setup='append_list=list();init_list=range(10)', number=100000) print('append_time_timeit: ', append_time_timeit)
由于時(shí)間很長(zhǎng),代碼中特意將 number 從一百萬次改成了十萬次。運(yùn)行結(jié)果如下:
('insert_time_timeit: ', 330.46189400000003) ('append_time_timeit: ', 0.21436310000001413)
相對(duì)來說,對(duì)于相同的操作,使用函數(shù)的運(yùn)行時(shí)間遠(yuǎn)小于直接傳入代碼表達(dá)式的時(shí)間,頭部插入數(shù)據(jù)的尤其明顯。
二、使用 repeat() 函數(shù)測(cè)試運(yùn)行時(shí)間
1. repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number) 函數(shù)介紹
repeat() 函數(shù)有五個(gè)參數(shù),每個(gè)參數(shù)都是關(guān)鍵字參數(shù),都有默認(rèn)值。相比 timeit() 函數(shù)而言,timeit() 函數(shù)有的參數(shù) repeat() 函數(shù)都有,此外,repeat() 函數(shù)多了一個(gè) repeat 參數(shù)。
repeat:表示測(cè)試要重復(fù)幾次,可以理解為將相同參數(shù)的 timeit() 函數(shù)重復(fù)執(zhí)行。最終的結(jié)果構(gòu)成一個(gè)列表返回,repeat 默認(rèn)為3次。
2. 測(cè)試函數(shù)的運(yùn)行時(shí)間
現(xiàn)在使用 repeat() 來測(cè)試上面兩個(gè)函數(shù)的運(yùn)行時(shí)間。
insert_time_repeat = timeit.repeat(stmt='insert_time_test()', setup='from __main__ import insert_time_test') print('insert_time_repeat: ', insert_time_repeat) append_time_repeat = timeit.repeat(stmt='append_time_test()', setup='from __main__ import append_time_test') print('append_time_repeat: ', append_time_repeat)
運(yùn)行結(jié)果如下:
('insert_time_repeat: ', [2.7707739, 2.908885, 2.7164823999999994]) ('append_time_repeat: ', [1.7458063, 1.777368000000001, 1.8675014999999995])
3. 測(cè)試代碼(表達(dá)式)的運(yùn)行時(shí)間
繼續(xù)使用 repeat() 測(cè)試上面代碼的運(yùn)行時(shí)間,直接傳入代碼,上面將 number 改成十萬次后,時(shí)間還是很長(zhǎng)(300多秒),所以繼續(xù)減小 number ,改成一萬次。
insert_time_repeat = timeit.repeat(stmt='list(insert_list.insert(0, i) for i in init_list)', setup='insert_list=list();init_list=range(10)', repeat=5, number=10000) print('insert_time_repeat: ', insert_time_repeat) append_time_repeat = timeit.repeat(stmt='list(append_list.append(i) for i in init_list)', setup='append_list=list();init_list=range(10)', repeat=5, number=10000) print('append_time_repeat: ', append_time_repeat)
運(yùn)行結(jié)果如下:
('insert_time_repeat: ', [2.591015, 2.5814996999999997, 2.5547322, 2.6153070000000005, 2.5496864000000006]) ('append_time_repeat: ', [0.0181692999999985, 0.01746889999999901, 0.018901899999999472, 0.018737400000000903, 0.018211900000000725])
三、使用 Timer 類測(cè)試運(yùn)行時(shí)間
1. Timer 類介紹
上面使用了 timeit() 函數(shù)和 repeat() 函數(shù),其實(shí)在 timeit 模塊中,這兩個(gè)函數(shù)都是對(duì) Timer 類做了進(jìn)一步的封裝,實(shí)際調(diào)用的還是 Timer 類中的方法。
在 Timer 類中,實(shí)現(xiàn)了兩個(gè)方法,timeit() 方法和 repeat() 方法,上面兩個(gè)函數(shù)調(diào)用的就是這兩個(gè)方法。
在使用 from timeit import ... 時(shí),只能導(dǎo)入 Timer 類,所以可以直接使用 Timer 類來測(cè)試,可以自己去調(diào)用方法,使用起來更靈活。
2. 測(cè)試列表頭部添加
先實(shí)例化一個(gè) Timer 類的對(duì)象,實(shí)例化時(shí)傳入 stmt 和 setup 參數(shù)(參數(shù)的含義與上面一致),timer 參數(shù)保持默認(rèn),然后通過實(shí)例對(duì)象調(diào)用對(duì)應(yīng)的 timeit() 方法或 repeat() 方法,在 timeit() 方法中傳入 number,在repeat() 方法中傳入 number 和 repeat 。
使用 timeit() 方法和 repeat() 方法測(cè)試從頭部添加數(shù)據(jù)的運(yùn)行時(shí)間。
timer_insert = timeit.Timer(stmt='insert_time_test()', setup='from __main__ import insert_time_test') insert_time_timeit = timer_insert.timeit(number=1000000) print('insert_time_timeit: ', insert_time_timeit) insert_time_repeat = timer_insert.repeat(number=1000000) print('insert_time_repeat: ', insert_time_repeat)
運(yùn)行結(jié)果如下:
('insert_time_timeit: ', 2.7732486) ('insert_time_repeat: ', [2.7367806999999997, 2.707402600000001, 2.7288245999999994])
3. 測(cè)試列表尾部添加
使用 timeit() 方法和 repeat() 方法測(cè)試從尾部添加數(shù)據(jù)的運(yùn)行時(shí)間。
timer_append = timeit.Timer(stmt='append_time_test()', setup='from __main__ import append_time_test') append_time_timeit = timer_append.timeit(number=1000000) print('append_time_timeit: ', append_time_timeit) append_time_repeat = timer_append.repeat(number=1000000) print('append_time_repeat: ', append_time_repeat)
運(yùn)行結(jié)果如下:
('append_time_timeit: ', 1.9966106000000001) ('append_time_repeat: ', [1.9523343999999998, 1.8373857999999998, 1.8695377000000004])
timeit 模塊是一個(gè)比較簡(jiǎn)單的模塊,大概用法就這些了。
總結(jié)
以上所述是小編給大家介紹的Python timeit模塊的使用實(shí)踐,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
Python中可復(fù)用函數(shù)的6種實(shí)踐
為了實(shí)現(xiàn)可維護(hù)性,我們的Python函數(shù)應(yīng)該:小型、只做一項(xiàng)任務(wù);沒有重復(fù);有一個(gè)層次的抽象性;有一個(gè)描述性的名字和有少于四個(gè)參數(shù),下面我們就來看看這6個(gè)特性的實(shí)踐吧2023-08-08Python網(wǎng)絡(luò)通訊之TCP協(xié)議實(shí)現(xiàn)服務(wù)器和客戶端實(shí)例
這篇文章主要介紹了Python網(wǎng)絡(luò)通訊之TCP協(xié)議實(shí)現(xiàn)服務(wù)器和客戶端實(shí)例, socket編程一種獨(dú)立于協(xié)議的網(wǎng)絡(luò)編程接口,應(yīng)用程序可以通過它發(fā)送或接收數(shù)據(jù),可對(duì)其進(jìn)行像對(duì)文件一樣的打開、讀寫和關(guān)閉等操作,需要的朋友可以參考下2023-08-08Pandas借助Numpy實(shí)現(xiàn)優(yōu)化的條件檢索代碼
Numpy其實(shí)是最早的處理數(shù)據(jù)的Python庫,它的核心ndarray對(duì)象,是一個(gè)高效的n維數(shù)組結(jié)構(gòu),本文主要介紹了Pandas如何借助Numpy優(yōu)化條件檢索,感興趣的可以了解下2024-03-03Python的Flask框架Request請(qǐng)求對(duì)象詳解
這篇文章主要介紹了Python的Flask框架Request請(qǐng)求對(duì)象詳解,Flask是一個(gè)輕量級(jí)的基于Python的web框架,使用 method 屬性可以操作當(dāng)前請(qǐng)求方法,通過使用 form 屬性處理表單數(shù)據(jù),需要的朋友可以參考下2023-08-08python獲取命令行輸入?yún)?shù)列表的實(shí)例代碼
今天小編就為大家分享一篇python獲取命令行輸入?yún)?shù)列表的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06Python筆記之a(chǎn) = [0]*x格式的含義及說明
這篇文章主要介紹了Python筆記之a(chǎn) = [0]*x格式的含義及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05Python利用wxPython實(shí)現(xiàn)ocr識(shí)別圖片漢字程序
在這篇博客中,我們將介紹一個(gè)如何使用wxPython構(gòu)建的簡(jiǎn)單OCR識(shí)別圖片漢字應(yīng)用程序,文章的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2023-08-08Python IDE環(huán)境之 新版Pycharm安裝詳細(xì)教程
這篇文章主要介紹了Python IDE環(huán)境之 新版Pycharm安裝教程,本文教程給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03