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