profile模組和cprofile模組可以用來分析程式。它們的工作原理都一樣,唯一的區別是,cprofile模組是以c擴充套件的方式實現的,如此一來執行的速度也快了很多,也顯得比較流行。這兩個模組都可以用來收集覆蓋資訊(比如,有多少函式被執行了),也能夠收集效能資料。對乙個程式進行分析的最簡單的方法就是執行這個命令:
python -m cprofile someprogram.py
此外,也可以使用profile模組中的run函式:
run(command [, filename])
該函式會使用exec語句執行command中的內容。filename是可選的檔案儲存名,如果沒有filename的話,該命令的輸出會直接傳送到標準輸出上。
下面是分析器執行完成時的輸出報告:
126 function calls (6 primitive calls) in 5.130cpu seconds
ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)1 0.030 0.030 5.070 5.070 :1(?)121/1 5.020 0.041 5.020 5.020 book.py:11(process)1 0.020 0.020 5.040 5.040 book.py:5(?)2 0.000 0.000 0.000 0.000 exceptions.py:101(_ _init_ _)1 0.060 0.060 5.130 5.130 profile:0(execfile('book.py'))
00.000 0.000 profile:0(profiler)
當輸出中的第一列包含了兩個數字時(比如,121/1),後者是元呼叫(primitive call)的次數,前者是實際呼叫的次數(譯者注:只有在遞迴情況下,實際呼叫的次數才會大於元呼叫的次數,其他情況下兩者都相等)。對於絕大部分的應用程式來講使用該模組所產生的的分析報告就已經足夠了,比如,你只是想簡單地看一下你的程式花費了多少時間。然後,如果你還想將這些資料儲存下來,並在將來對其進行分析,你可以使用pstats模組。
假設你想知道你的程式究竟在**花費了多少時間。
如果你只是想簡單地給你的整個程式計時的話,使用unix中的time命令就已經完全能夠應付了。例如:
bash %time python3 someprogram.py
real 0m13.937s
user 0m12.162s
sys 0m0.098s
bash%
通常來講,分析**的程度會介於這兩個極端之間。比如,你可能已經知道你的**會在一些特定的函式中花的時間特別多。針對這類特定函式的分析,我們可以使用修飾器decorator,例如:
importtimefrom functools importwrapsdeftimethis(func):
start=time.perf_counter()
r= func(*args, **kwargs)
使用decorator的方式很簡單,你只需要把它放在你想要分析的函式的定義前面就可以了。例如:
>>>@timethis
...defcountdown(n):
...while n >0:
... n-= 1...>>> countdown(10000000)__main__.countdown : 0.803001880645752
如果想要分析乙個語句塊的話,你可以定義乙個上下文管理器(context manager)。例如:
importtimefrom contextlib importcontextmanager
@contextmanagerdeftimeblock(label):
start=time.perf_counter()try:yield
finally:
end=time.perf_counter()print('{} : {}'.format(label, end - start))
接下來是如何使用上下文管理器的例子:
>>> with timeblock('counting'):
... n= 10000000...while n >0:
... n-= 1...
counting :1.5551159381866455
如果想研究一小段**的效能的話,timeit模組會非常有用。例如:
>>> from timeit importtimeit>>> timeit('math.sqrt(2)', 'import math')0.1432319980012835
>>> timeit('sqrt(2)', 'from math import sqrt')0.10836604500218527
timeit的工作原理是,將第乙個引數中的語句執行100萬次,然後計算所花費的時間。第二個引數指定了一些測試之前需要做的環境準備工作。如果你需要改變迭代的次數,可以附加乙個number引數,就像這樣:
>>> timeit('math.sqrt(2)', 'import math', number=10000000)1.434852126003534
>>> timeit('sqrt(2)', 'from math import sqrt', number=10000000)1.0270336690009572
當進行效能評估的時候,要牢記任何得出的結果只是乙個估算值。函式time.perf_counter()能夠在任一平台提供最高精度的計時器。然而,它也只是記錄了自然時間,記錄自然時間會被很多其他因素影響,比如,計算機的負載。如果你對處理時間而非自然時間感興趣的話,你可以使用time.process_time()。例如:
importtimefrom functools importwrapsdeftimethis(func):
start=time.process_time()
r= func(*args, **kwargs)
最後也是相當重要的就是,如果你想做乙個詳細的效能評估的話,你最好查閱time,timeit以及其他相關模組的文件,這樣你才能夠對平台相關的不同之處有所了解。
profile模組中最基礎的東西就是run()函式了。該函式會把乙個語句字串作為引數,然後在執行語句時生成所花費的時間報告。
importprofiledeffib(n):#from literateprograms.org
#if n ==0:return0elif n == 1:return 1
else:return fib(n-1) + fib(n-2)deffib_seq(n):
seq=if n >0:
seq.extend(fib_seq(n-1))
profile.run('print(fib_seq(20)); print')
python函式解讀 python 函式解讀
1 strip 函式 用於移除字串頭尾指定的字元 預設為空格或換行符 或字串行 包括 n r t 注意 該方法只能刪除開頭或是結尾的字元,不能刪除中間部分的字元 語法 s.strip rm 刪除s字串中開頭 結尾處,位於 rm刪除序列的字元 s.lstrip rm 刪除s字串中開頭處,位於 rm刪除...
python解讀 Python再次解讀筆記
書讀百遍,其義自見。如果乙個字串包含很多需要轉義的字元,對每乙個字元都進行轉義會很麻煩。為了避免這種情況,我們可以在字串前面加個字首r,表示這是乙個 raw 字串,裡面的字元就不需要轉義了。布林運算 1.在計算a and b時,如果 a 是 false,則根據與運算法則,整個結果必定為 false,...
python的小程式 一些基礎的python小程式
1.求下列數奇偶分數 list1 1,2,3,4,5,6,7,8,9,10 先建立兩個空列表 jishu oushu 使用for迴圈迭代list1一一取出進行判斷 for i in list1 取出的數除以2的餘數等於0加入偶數列表,否則是奇數 if i 2 0 else 列印新列表 print j...