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=10**4
data=[randint(0,max_size) for _ in range(max_size)]
test= lambda :insert_sort(data)
return test
分析代码:
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()
分析结果:
root@native-sunaihua-5-25-18:~/pdb_test# python test.py
20003 function calls in 1.195 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.195 1.195 test.py:21(<lambda>)
1 0.003 0.003 1.195 1.195 test.py:5(insert_sort)
10000 1.174 0.000 1.191 0.000 test.py:11(insert_value)
9992 0.018 0.000 0.018 0.000 {method 'insert' of 'list' objects}
8 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {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:21(<lambda>) <-
test.py:5(insert_sort) <- 1 0.004 1.221 test.py:21(<lambda>)
test.py:11(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/