python性能调试过程中最突出的问题是耗时。性能测试工具很多。这里介绍cprofile和line_profiler的搭配使用方法。前者返回项目中每个函数的耗时,后者可以分析每个函数行的耗时。
一,cProfile
cprofile是python默认的性能分析器
cprofile是一种只测量CPU时间的确定性分析器,不关心与内存相关的内存消耗和其他信息。
参数分析:
run(statement,filename=None,sort=-1) #statement:代码或函数(函数名)需要测试 #fielname:结果保存的位置默认为stdout #sort:常用的结果排序方法有‘结果排序法’cumtime':积累时间,name':函数名,‘line':行号 #以及以下结果分析中的‘’ncalls'等
使用方法1:
importre importcProfile cProfile.run('re.compile("abc")')
结果分析:
第一行:监控129个函数调用,其中128个是原生调用(不涉及递归)
ncalls:函数被调用的次数。若该列有两个值,则表示有递归调用,第二个值为原生调用次数,第一个值为总调用次数。
tottime:函数内部消耗的总时间。(有助于优化)
percall:tottime除以ncalls,一个函数每次调用平均消耗时间。
cumtime:以前所有子函数的消耗时间都是累积的。
filename:lineno(function):分析函数所在的文件名、行号、函数名。
使用方法二:
importcProfile importre cProfile.run('re.compile("abc")','result.out','cumtime')
使用方法三:控制台
终端:python-mcProfile-oresult.out-scumulativetest.py #效果与方法二相同
结果分析:
结果保存在文件名称result.在out二进制文件中。
读取结果:pstats模块和stats类别
importpstats defview_profile(path): p=pstats.Stats(f"{path}") p.sort_stats("cumulative")#表示结果按累计时间消耗排序,其他排序与上面相同 p.print_stats(3)#输出结果输出结果的前三行,参数也可以是0和1之间的小数,表示输出结果的比例,没有参数表示所有输出结果 p.print_callers()#可以显示哪些函数可以调用函数 p.print_callees()#可以显示哪个函数可以调用哪些函数
二,line_profiler
这种性能分析器不同于cprofile,它可以帮助你一行一行地分析性能。
若瓶颈问题在某一行,则需要line_profiler来解决。
建议使用kernprof工具
安装
pipinstallline_profiler
使用方法1:kernprof
@profile deffib(n): #文件名aaa.py a,b=0,1 foriinrange(0,n): a,b=b,a+b returna fib(5)
终端:kernprof-l-vaaa.py #-l表示逐行分析-v用于控制台输出,无需添加-v将分析结果写入aaaa。.py.lprof文件
使用方法二:函数调用
fromline_profilerimportLineProfiler deftest_line(func_name,parameter=None): “”“ :param:func_name,str,函数名 :param:parameter,函数参数 ”“” lp=LineProfiler() lp_wrapper=lp(func_name) ifparameterisnotNone: lp_wrapper(parameter)#如果有参数,没有参数就不用写了 lp.print_stats()#显示结果
结果分析
Line:文件中的行号。
Hits:代码在性能分析中执行的次数。
Time:代码执行的总时间由计数器决定。
Per Hit:平均消耗一段代码的时间。
% Time:执行代码消耗比例一段时间。
三、搭配使用
首先用cprofile确定项目中耗时最多的函数,然后用line_profiler分析这些耗时最多的函数,确定行性能瓶颈。
更多Python知识,请关注Python视频教程!!