Why Profile
即使我们的代码已经非常Pythonic了,但运行效率还是不能满足要求。性能问题符合20/80规则,即20%的代码引起了80%的性能损耗。为了快速定位瓶颈代码,推荐通过Profile来分析,能到达事半功倍的效果。
Python Profile
对于Python,比较常用的Profile工具有三个:
- profile 纯python语言实现,返回函数整体损耗。(自带)[详情]
- cProfile 同profile,部分实现native化,返回函数整体损耗。(自带)
- line_profile 返回函数每行损耗。(第三方)[详情]
Profile Usage
- profile
# 这里使用vsm模型进行测试
from profile import Profile
p = Profile()
p.runcall(vsm, tags[0], tags[1])
p.print_stats()
# ncalls 函数总的调用次数
# tottime 函数内部(不包括子函数)的占用时间
# percall(第一个) tottime/ncalls
# cumtime 函数包括子函数所占用的时间
# percall(第二个)cumtime/ncalls
# filename:lineno(function) 文件:行号(函数)
212 function calls in 0.002 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
78 0.000 0.000 0.000 0.000 :0(append)
40 0.000 0.000 0.000 0.000 :0(count)
2 0.000 0.000 0.000 0.000 :0(keys)
3 0.000 0.000 0.000 0.000 :0(len)
78 0.000 0.000 0.000 0.000 :0(pow)
1 0.000 0.000 0.000 0.000 :0(range)
1 0.001 0.001 0.001 0.001 :0(setprofile)
1 0.000 0.000 0.000 0.000 :0(sqrt)
1 0.000 0.000 0.002 0.002 profile:0(<function vsm at 0x000000000233A278>)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 vsm.py:12(create_vocabulary)
2 0.000 0.000 0.000 0.000 vsm.py:17(calc_tag_frequency)
2 0.000 0.000 0.000 0.000 vsm.py:26(create_vector)
1 0.000 0.000 0.001 0.001 vsm.py:38(calc_similar)
1 0.000 0.000 0.001 0.001 vsm.py:52(vsm)
- line_profile
# 这里使用vsm模型进行测试
from line_profiler import LineProfiler
lp = LineProfiler()
lp_vsm = lp(vsm)
lp_vsm(tags[0], tags[1])
lp.print_stats()
# Total Time:测试代码的总运行时间
# Line:代码行号
# Hits:表示每行代码运行的次数
# Time:每行代码运行的总时间
# Per Hits:每行代码运行一次的时间
# % Time:每行代码运行时间的百分比
Timer unit: 1e-07 s
Total time: 0.000219 s
File: vsm.py
Function: vsm at line 52
Line # Hits Time Per Hit % Time Line Contents
==============================================================
52 def vsm(tag_list1, tag_list2, debug=False):
53 1 59.0 59.0 2.7 count = len(tag_list1) + len(tag_list2)
54 1 123.0 123.0 5.6 vocabulary = create_vocabulary(tag_list1, tag_list2)
55 1 677.0 677.0 30.9 vector1 = create_vector(calc_tag_frequency(tag_list1), vocabulary)
56 1 530.0 530.0 24.2 vector2 = create_vector(calc_tag_frequency(tag_list2), vocabulary)
57 1 777.0 777.0 35.5 similar = calc_similar(vector1, vector2, count)
58 1 24.0 24.0 1.1 return similar
Profile GUI
虽然Profile的输出已经比较直观,但还是推荐保存profile结果,然后使用图形化工具从不同维度进行分析,更快地找出瓶颈代码。
常用的Profile图形化工具有:
-
VisualPyTune
下载地址:http://code.google.com/p/visualpytune/downloads/list
VisualPyTune
-
QCacheGrind
下载地址:https://jaist.dl.sourceforge.net/project/qcachegrindwin/0.7.4/qcachegrind074-x64.zip
QCacheGrind
-
RunSnakeRun
官网:http://www.vrplumber.com/programming/runsnakerun/
RunSnakeRun