Python如何給你的程序做性能測(cè)試
問(wèn)題
你想測(cè)試你的程序運(yùn)行所花費(fèi)的時(shí)間并做性能測(cè)試。
解決方案
如果你只是簡(jiǎn)單的想測(cè)試下你的程序整體花費(fèi)的時(shí)間, 通常使用Unix時(shí)間函數(shù)就行了,比如:
bash % time python3 someprogram.py real 0m13.937s user 0m12.162s sys 0m0.098s bash %
如果你還需要一個(gè)程序各個(gè)細(xì)節(jié)的詳細(xì)報(bào)告,可以使用 cProfile 模塊:
bash % python3 -m cProfile someprogram.py 859647 function calls in 16.016 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 263169 0.080 0.000 0.080 0.000 someprogram.py:16(frange) 513 0.001 0.000 0.002 0.000 someprogram.py:30(generate_mandel) 262656 0.194 0.000 15.295 0.000 someprogram.py:32(<genexpr>) 1 0.036 0.036 16.077 16.077 someprogram.py:4(<module>) 262144 15.021 0.000 15.021 0.000 someprogram.py:4(in_mandelbrot) 1 0.000 0.000 0.000 0.000 os.py:746(urandom) 1 0.000 0.000 0.000 0.000 png.py:1056(_readable) 1 0.000 0.000 0.000 0.000 png.py:1073(Reader) 1 0.227 0.227 0.438 0.438 png.py:163(<module>) 512 0.010 0.000 0.010 0.000 png.py:200(group) ... bash %
不過(guò)通常情況是介于這兩個(gè)極端之間。比如你已經(jīng)知道代碼運(yùn)行時(shí)在少數(shù)幾個(gè)函數(shù)中花費(fèi)了絕大部分時(shí)間。 對(duì)于這些函數(shù)的性能測(cè)試,可以使用一個(gè)簡(jiǎn)單的裝飾器:
# timethis.py import time from functools import wraps def timethis(func): @wraps(func) def wrapper(*args, **kwargs): start = time.perf_counter() r = func(*args, **kwargs) end = time.perf_counter() print('{}.{} : {}'.format(func.__module__, func.__name__, end - start)) return r return wrapper
要使用這個(gè)裝飾器,只需要將其放置在你要進(jìn)行性能測(cè)試的函數(shù)定義前即可,比如:
>>> @timethis ... def countdown(n): ... while n > 0: ... n -= 1 ... >>> countdown(10000000) __main__.countdown : 0.803001880645752 >>>
要測(cè)試某個(gè)代碼塊運(yùn)行時(shí)間,你可以定義一個(gè)上下文管理器,例如:
from contextlib import contextmanager @contextmanager def timeblock(label): start = time.perf_counter() try: yield finally: end = time.perf_counter() print('{} : {}'.format(label, end - start))
下面是使用這個(gè)上下文管理器的例子:
>>> with timeblock('counting'): ... n = 10000000 ... while n > 0: ... n -= 1 ... counting : 1.5551159381866455 >>>
對(duì)于測(cè)試很小的代碼片段運(yùn)行性能,使用 timeit 模塊會(huì)很方便,例如:
>>> from timeit import timeit >>> timeit('math.sqrt(2)', 'import math') 0.1432319980012835 >>> timeit('sqrt(2)', 'from math import sqrt') 0.10836604500218527 >>>
timeit 會(huì)執(zhí)行第一個(gè)參數(shù)中語(yǔ)句100萬(wàn)次并計(jì)算運(yùn)行時(shí)間。 第二個(gè)參數(shù)是運(yùn)行測(cè)試之前配置環(huán)境。如果你想改變循環(huán)執(zhí)行次數(shù), 可以像下面這樣設(shè)置 number 參數(shù)的值:
>>> timeit('math.sqrt(2)', 'import math', number=10000000) 1.434852126003534 >>> timeit('sqrt(2)', 'from math import sqrt', number=10000000) 1.0270336690009572 >>>
討論
當(dāng)執(zhí)行性能測(cè)試的時(shí)候,需要注意的是你獲取的結(jié)果都是近似值。 time.perf_counter() 函數(shù)會(huì)在給定平臺(tái)上獲取最高精度的計(jì)時(shí)值。 不過(guò),它仍然還是基于時(shí)鐘時(shí)間,很多因素會(huì)影響到它的精確度,比如機(jī)器負(fù)載。 如果你對(duì)于執(zhí)行時(shí)間更感興趣,使用 time.process_time() 來(lái)代替它。例如:
from functools import wraps def timethis(func): @wraps(func) def wrapper(*args, **kwargs): start = time.process_time() r = func(*args, **kwargs) end = time.process_time() print('{}.{} : {}'.format(func.__module__, func.__name__, end - start)) return r return wrapper
最后,如果你想進(jìn)行更深入的性能分析,那么你需要詳細(xì)閱讀 time 、timeit 和其他相關(guān)模塊的文檔。 這樣你可以理解和平臺(tái)相關(guān)的差異以及一些其他陷阱。 還可以參考13.13小節(jié)中相關(guān)的一個(gè)創(chuàng)建計(jì)時(shí)器類的例子。
以上就是Python如何給你的程序做性能測(cè)試的詳細(xì)內(nèi)容,更多關(guān)于Python做性能測(cè)試的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于python圖書館管理系統(tǒng)設(shè)計(jì)實(shí)例詳解
這篇文章主要介紹了基于python圖書館管理系統(tǒng)設(shè)計(jì)實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08利用python如何實(shí)現(xiàn)貓捉老鼠小游戲
這篇文章主要給大家介紹了關(guān)于利用python如何實(shí)現(xiàn)貓捉老鼠小游戲的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Python實(shí)現(xiàn)雙軸組合圖表柱狀圖和折線圖的具體流程
這篇文章主要介紹了Python雙軸組合圖表柱狀圖+折線圖,Python繪制雙軸組合的關(guān)鍵在plt庫(kù)的twinx()函數(shù),具體實(shí)例代碼跟隨小編一起看看吧2021-08-08Pandas DataFrame replace替換后無(wú)效的解決
這篇文章主要介紹了Pandas DataFrame replace替換后無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08pytorch方法測(cè)試詳解——?dú)w一化(BatchNorm2d)
今天小編就為大家分享一篇pytorch方法測(cè)試詳解——?dú)w一化(BatchNorm2d),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01pymongo為mongodb數(shù)據(jù)庫(kù)添加索引的方法
這篇文章主要介紹了pymongo為mongodb數(shù)據(jù)庫(kù)添加索引的方法,涉及Python操作mongodb數(shù)據(jù)庫(kù)的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-05-05和孩子一起學(xué)習(xí)python之變量命名規(guī)則
這篇文章我們給大家總結(jié)了關(guān)于兒童學(xué)習(xí)python中的變量命名規(guī)則相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友跟著參考學(xué)習(xí)下。2018-05-05Python讀取英文文件并記錄每個(gè)單詞出現(xiàn)次數(shù)后降序輸出示例
這篇文章主要介紹了Python讀取英文文件并記錄每個(gè)單詞出現(xiàn)次數(shù)后降序輸出,涉及Python文件讀取、字符串替換、分割以及字典遍歷、排序等相關(guān)操作技巧,需要的朋友可以參考下2018-06-06