天天看點

使用cProfiler對Python程式進行性能分析介紹實踐其他方式

介紹

profiler是一個程式,用來描述運作時的程式性能,并且從不同方面提供統計資料加以表述。

Python中含有3個子產品提供這樣的功能,分别是cProfile,profile和pstats。這些分析器提供的是對Python程式的确定性分析。同時也提供一系列的報表生成工具,允許使用者快速地檢查分析結果。

Python标準庫提供了3個不同的性能分析器:

- cProfile,推薦給大部分的使用者,是C的一個擴充應用,因為其合理的運作開銷,是以适合分析運作時間較長的。是基于lsprof。

- profile,一個純python子產品,它的接口和cProfile一緻。在分析程式時,增加了很大的運作開銷。如果你想擴充profiler的功能,可以試着繼承這個子產品

- hotshot, 一個試驗性的c子產品,關注減少分析時的運作開銷,但是是以需要更長的資料後處理的次數為代價。不過這個子產品不再被維護,也有可能在新的python版本中被棄用。

實踐

源碼

from random import randint
from cProfile import Profile
import pstats

def insert_sort(data):
    result=[]
    for value in data:
        insert_value(result,value)
    return result

def insert_value(result,value):
    for i,existing in enumerate(result):
        if existing > value:
            result.insert(i,value)
            return
    result.append(value)

def main():
    max_size=**
    data=[randint(,max_size) for _ in range(max_size)]
    test= lambda :insert_sort(data)
    return test
           

使用cProfile進行分析

分析代碼:

def anylize_by_cprofile():
    profile=Profile()
    profile.runcall(main())
    stats=pstats.Stats(profile)
    stats.strip_dirs()  #從所有子產品名中去掉無關的路徑資訊
    stats.sort_stats('cumulative')
    stats.print_stats()

anylize_by_cprofile()
           

分析結果:

[email protected]:~/pdb_test# python test.py 
         20003 function calls in 1.195 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
                         test.py:(<lambda>)
                         test.py:(insert_sort)
                     test.py:(insert_value)
                      {method 'insert' of 'list' objects}
                         {method 'append' of 'list' objects}
                         {method 'disable' of '_lsprof.Profiler' objects}
           

結果說明

- ncalls:總的調用次數

- totime:消耗的時間,不包括調用其他函數的時間

- tottime percall:每次調用該函數的時間,不包括調用其他函數的時間

- cumtime:消耗的總時間,包括調用其他函數的實踐

- cumtime percall:每次調用該函數的時間,包括調用其他函數的時間

不足:

上面的資訊隻是列出了每個函數的執行資訊,但是沒有列出調用關系,如果想檢視調用關系,可以執行stats.print_callers()方法,結果如下:

Ordered by: cumulative time

Function                                          was called by...
                                                      ncalls  tottime  cumtime
test.py:(<lambda>)                              <-
test.py:5(insert_sort)                            <-       1    0.004    1.221  test.py:21(<lambda>)
test.py:(insert_value)                          <-   10000    1.199    1.217  test.py:5(insert_sort)
{method 'insert' of 'list' objects}               <-    9992    0.018    0.018  test.py:11(insert_value)
{method 'append' of 'list' objects}               <-       8    0.000    0.000  test.py:11(insert_value)
{method 'disable' of '_lsprof.Profiler' objects}  <-
           

其他方式

在GUI的系統中,還可以通過更加進階的方式進行分析與調試,例如使用RunSnakeRun,或是KCachegrind,詳細說明可參見:http://blog.jobbole.com/52090/