一、Python cprofile 简介
Python 自带的 cprofile 库,可以对代码的每部分进行很方便的动态分析;
比如准确计算出每个模块消耗的时间等。这样你就可以知道程序的瓶颈所在,从而方便针对性地对其进行修正或优化。
二、Python cprofile 使用方法
1、import 使用
#!/usr/bin/python2.7
# test.py
import time
import cProfile
import pdb
pdb.set_trace()
def testcal(a, b, c):
e = (a + b) * c
print "(a + b) * c =", e
e = ((a + b) * c)
print "((a + b) * c) =", e
time.sleep(5) # 测试执行耗时
e = a + (b * c)
print "a + (b * c) =", e
if __name__=='__main__':
a = 20
b = 10
c = 15
cProfile.run('testcal(a, b, c)')
2、命令行直接用
python -m cProfile test.py
三、Python cprofile 输出简析
运行结果如下所示:
/tmp/test.py(9)<module>()
-> a = 20
(Pdb) c
(a + b) * c = 450
((a + b) * c) = 450
a + (b * c) = 170
42 function calls in 6.483 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 UserDict.py:18(__getitem__)
1 0.000 0.000 0.000 0.000 UserDict.py:70(__contains__)
1 0.000 0.000 0.000 0.000 bdb.py:1(<module>)
1 0.000 0.000 0.000 0.000 bdb.py:10(BdbQuit)
1 0.000 0.000 0.000 0.000 bdb.py:14(Bdb)
2 0.000 0.000 0.000 0.000 bdb.py:176(_set_stopinfo)
1 0.000 0.000 0.000 0.000 bdb.py:192(set_step)
1 0.000 0.000 0.000 0.000 bdb.py:212(set_trace)
1 0.000 0.000 0.000 0.000 bdb.py:23(__init__)
1 0.000 0.000 0.000 0.000 bdb.py:39(reset)
1 0.000 0.000 0.000 0.000 bdb.py:449(Breakpoint)
1 0.000 0.000 0.000 0.000 bdb.py:614(Tdb)
1 0.000 0.000 0.000 0.000 cmd.py:46(<module>)
1 0.000 0.000 0.000 0.000 cmd.py:55(Cmd)
1 0.000 0.000 0.000 0.000 cmd.py:79(__init__)
1 0.000 0.000 0.000 0.000 fnmatch.py:11(<module>)
1 0.000 0.000 0.000 0.000 linecache.py:43(checkcache)
1 0.000 0.000 0.000 0.000 pdb.py:107(reset)
1 0.000 0.000 0.000 0.000 pdb.py:111(forget)
1 0.000 0.000 0.001 0.001 pdb.py:1250(set_trace)
1 0.000 0.000 0.000 0.000 pdb.py:18(Restart)
1 0.001 0.001 0.001 0.001 pdb.py:3(<module>)
1 0.000 0.000 0.000 0.000 pdb.py:59(Pdb)
1 0.001 0.001 0.001 0.001 pdb.py:61(__init__)
1 0.000 0.000 0.000 0.000 posixpath.py:68(join)
1 0.000 0.000 0.000 0.000 pprint.py:35(<module>)
1 0.000 0.000 0.000 0.000 pprint.py:84(PrettyPrinter)
1 0.000 0.000 0.000 0.000 repr.py:1(<module>)
2 0.000 0.000 0.000 0.000 repr.py:10(__init__)
1 0.000 0.000 0.000 0.000 repr.py:8(Repr)
1 1.477 1.477 6.483 6.483 test.py:3(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method 'keys' of 'dict' objects}
1 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects}
2 0.000 0.000 0.000 0.000 {open}
1 0.000 0.000 0.000 0.000 {sys._getframe}
1 0.000 0.000 0.000 0.000 {sys.settrace}
1 5.004 5.004 5.004 5.004 {time.sleep}
输出内容字段简析:
1、ncalls : 是指相应代码 / 函数被调用的次数;
2、tottime: 是指对应代码 / 函数总共执行所需要的时间(注意,并不包括它调用的其他代码 / 函数的执行时间);
3、percall: 就是上述两者相除的结果,也就是 tottime / ncalls;
4、cumtime:则是指对应代码 / 函数总共执行所需要的时间,这里包括了它调用的其他代码 / 函数的执行时间;
5、percall: 则是 cumtime 和 ncalls 相除的平均结果。
了解这些参数后,再看看上面的输出结果;
可以很清晰地看出来,这段程序执行较耗时的地方,在于 {time.sleep}
和 test.py:3(<module>)
。