Python學習 python效能分析

2022-05-04 18:33:09 字數 4083 閱讀 6243

python profiler效能分析

一種方法:

if __name__ == "__main__":

import profile

profile.run("foo()")

另一種命令列方法:python -m profile prof1.py

profile的統計結果分為ncalls, tottime, percall, cumtime, percall, filename:lineno(function)等若干列:

ncalls

函式的被呼叫次數

tottime

函式總計執行時間,除去函式中呼叫的函式執行時間

percall

函式執行一次的平均時間,等於tottime/ncalls

cumtime

函式總計執行時間,含呼叫的函式執行時間

percall

函式執行一次的平均時間,等於cumtime/ncalls

filename:lineno(function)

函式所在的檔名,函式的行號,函式名

用pstats自定義報表

profile解 決了我們的乙個需求,還有乙個需求:以多種形式檢視輸出,我們可以通過 profile的另乙個類stats來解決。在這裡我們需要引入乙個模組pstats,它定義了乙個類stats,stats的建構函式接受乙個引數—— 就是profile的輸出檔案的檔名。stats提供了對profile輸出結果進行排序、輸出控制等功能,如我們把前文的程式改為如下:

# …略

if __name__ == "__main__":

import profile

profile.run("foo()", "prof.txt")

import pstats

p = pstats.stats("prof.txt")

p.sort_stats("time").print_stats()

引入pstats之後,將profile的輸出按函式占用的時間排序

stats有若干個函式,這些函式組合能給我們輸出不同的profile報表,功能非常強大。下面簡單地介紹一下這些函式:

strip_dirs()

用以除去檔名前名的路徑資訊。

add(filename,[…])

把profile的輸出檔案加入stats例項中統計

dump_stats(filename)

把stats的統計結果儲存到檔案

sort_stats(key,[…])

最重要的乙個函式,用以排序profile的輸出

reverse_order()

把stats例項裡的資料反序重排

print_stats([restriction,…])

把stats報表輸出到stdout

print_callers([restriction,…])

輸出呼叫了指定的函式的函式的相關資訊

print_callees([restriction,…])

輸出指定的函式呼叫過的函式的相關資訊

這裡最重要的函式就是sort_stats和print_stats,通過這兩個函式我們幾乎可以用適當的形式瀏覽所有的資訊了,下面來詳細介紹一下。

sort_stats() 接受乙個或者多個字串引數,如」time」、」name」 等,表明要根據哪一列來排序,這相當有用,例如我們可以通過用time為key來排序得知最消耗時間的函式,也可以通過cumtime來排序,獲知總消耗 時間最多的函式,這樣我們優化的時候就有了針對性,也就事半功倍了。sort_stats可接受的引數如下:

『ncalls』

被呼叫次數

『cumulative』

函式執行的總時間

『file』

檔名『module』

檔名『pcalls』

簡單呼叫統計(相容舊版,未統計遞迴呼叫)

『line』

行號『name』

函式名『nfl』

name/file/line

『stdname』

標準函式名

『time』

函式內部執行時間(不計呼叫子函式的時間)

另乙個相當重要的函式就是print_stats——用以根據最後一次呼叫sort_stats之後得到的報表。

cprofile

python -m cprofile -s time test.py

timeit

timeit除了有非常友好的程式設計介面,也同樣提供了友好的命令列介面。首先來看看程式設計介面。timeit模組包含乙個類timer,它的建構函式是這樣的:

class timer( [stmt='pass' [, setup='pass' [, timer=]]])

stmt引數是字串形式的乙個**段,這個**段將被評測執行時間;setup引數用以設定stmt的執行環境;timer可以由使用者使用自定義精度的計時函式。

timeit.timer有三個成員函式,下面簡單介紹一下:

timeit( [number=1000000])

timeit()執行一次timer建構函式中的setup語句之後,就重複執行number次stmt語句,然後返回總計執行消耗的時間。

repeat( [repeat=3 [, number=1000000]])

repeat()函式以number為引數呼叫timeit函式repeat次,並返回總計執行消耗的時間

print_exc( [file=none])

print_exc()函式用以代替標準的tracback,原因在於print_exc()會輸出錯行的源**,如:

>>> t = timeit.timer("t = foo()/nprint t")      ß被timeit的**段

>>> t.timeit()

traceback (most recent call last):

file "", line 1, in -toplevel-

t.timeit()

file "e:/python23/lib/timeit.py", line 158, in timeit

return self.inner(it, self.timer)

file "", line 6, in inner

foo()         ß標準輸出是這樣的

nameerror: global name 'foo' is not defined

>>> try:

t.timeit()

except:

t.print_exc()

traceback (most recent call last):

file "", line 2, in ?

file "e:/python23/lib/timeit.py", line 158, in timeit

return self.inner(it, self.timer)

file "", line 6, in inner

t = foo()        ßprint_exc()的輸出是這樣的,方便定位錯誤

nameerror: global name 'foo' is not defined

除了可以使用timeit的程式設計介面外,我們也可以在命令列裡使用timeit,非常方便:

python timeit.py [-n n] [-r n] [-s s] [-t] [-c] [-h] [statement ...]

其中引數的定義如下:

-n n/--number=n

statement語句執行的次數

-r n/--repeat=n

重複多少次呼叫timeit(),預設為3

-s s/--setup=s

用以設定statement執行環境的語句,預設為」pass」

-t/--time

計時函式,除了windows平台外預設使用time.time()函式,

-c/--clock

計時函式,windows平台預設使用time.clock()函式

-v/--verbose

輸出更大精度的計時數值

-h/--help

Python學習之物件的動態性

物件可以使用del語句刪掉,刪掉之後將不能再呼叫該物件。也可以為物件動態的新增方法。但是動態新增的方法,python不會自動的將呼叫者繫結到self上,需要手動繫結 繫結的同時即呼叫 例如 假設某個類的例項是p,再類外,有乙個準備新增的新方法,叫做newfunc def newfunc self p...

python 多型性 Python 多型

返回python教程首頁 多型介紹多型之前,我們先看看什麼叫方法重寫。方法重寫 子類繼承父類,會繼承父類的所有方法,當父類方法無法滿足需求,可在子類中定義乙個同名方法覆蓋父類的方法,這就叫方法重寫。當子類的例項呼叫該方法時,優先呼叫子類自身定義的方法,因為它被重寫了。例如 class people ...

python原子性 python 檔案原子寫入

python 檔案原子寫入 1.檔案原子寫入 你的 以寫的方式開啟了乙個檔案,執行寫入操作,但在寫入過程中,發生了異常,導致程式崩潰,這個時候,檔案裡已經有了一部分你寫入的資料,但是不完整,這往往是乙個不被接受的結果。檔案原子寫入,是指一次寫入操作,要麼是全部資料都寫入檔案,要麼是全部資料都沒有寫入...