python函数性能测试的简单介绍( 六 )


这种输出信息要比timeit模块的原始计时信息富有启发意义的多 。我们立即可以发现,function_b()与function_c()使用了被调用5000次以上的生成器,使得它们的速度至少要比function_a()慢10倍以上 。并且,function_b()调用了更多通常意义上的函数,包括调用内置的sorted()函数,这使得其几乎比function_c()还要慢两倍 。当然,timeit() 模块提供了足够的信息来查看计时上存在的这些差别 , 但cProfile模块允许我们了解为什么会存在这些差别 。正如timeit模块允许对代码进行计时而又不需要对其监控一样 , cProfile模块也可以做到这一点 。然而,从命令行使用cProfile模块时,我们不能精确地指定要执行的 是什么——而只是执行给定的程序或模块,并报告所有这些的计时结果 。需要使用的 命令行是python3 -m cProfile programOrModule.py,产生的输出信息与前面看到的一 样,下面给出的是输出信息样例,格式上进行了一些调整,并忽略了大多数行:
10272458 function calls (10272457 primitive calls) in 37.718 CPU secs
ncalls tottime percall cumtime percall filename:lineno(function)
10.000 0.000 37.718 37.718:1 ( )
10.719 0.719 37.717 37.717:12( )
1000 1.569 0.002 1.569 0.002:20(function_a)
1000 0.011 0.000 22.560 0.023:27(function_b)
5128000 7.078 0.000 7.078 0.000:28( )
1000 6.510 0.007 12.825 0.013:35(function_c)
5128000 6.316 0.000 6.316 0.000:36( )
在cProfile术语学中,原始调用指的就是非递归的函数调用 。
以这种方式使用cProfile模块对于识别值得进一步研究的区域是有用的 。比如 , 这里 我们可以清晰地看到function_b()需要耗费更长的时间,但是我们怎样获取进一步的详细资料?我们可以使用cProfile.run("function_b()")来替换对function_b()的调用 。或者可以保存完全的profile数据并使用pstats模块对其进行分析 。要保存profile,就必须对命令行进行稍许修改:python3 -m cProfile -o profileDataFile programOrModule.py 。之后可以对 profile 数据进行分析 , 比如启动IDLE,导入pstats模块 , 赋予其已保存的profileDataFile,或者也可以在控制台中交互式地使用pstats 。
下面给出的是一个非常短的控制台会话实例 , 为使其适合页面展示,进行了适当调整,我们自己的输入则以粗体展示:
$ python3 -m cProfile -o profile.dat MyModule.py
$ python3 -m pstats
Welcome to the profile statistics browser.
% read profile.dat
profile.dat% callers function_b
Random listing order was used
List reduced from 44 to 1 due to restriction
Function was called by...
ncalls tottime cumtime
:27(function_b) - 1000 0.011 22.251:12( )
profile.dat% callees function_b
Random listing order was used
List reduced from 44 to 1 due to restriction
Function called...
ncalls tottime cumtime
:27(function_b)-
1000 0.005 0.005 built-in method bisectJeft
1000 0.001 0.001 built-in method len
1000 1 5.297 22.234 built-in method sorted
profile.dat% quit
输入help可以获取命令列表,help后面跟随命令名可以获取该命令的更多信息 。比如, help stats将列出可以赋予stats命令的参数 。还有其他一些可用的工具 , 可以提供profile数据的图形化展示形式,比如 RunSnakeRun (), 该工具需要依赖于wxPython GUI库 。
使用timeit与cProfile模块,我们可以识别出我们自己代码中哪些区域会耗费超过预期的时间;使用cProfile模块,还可以准确算岀时间消耗在哪里 。
以上内容部分摘自视频课程 05后端编程Python-19调试、测试和性能调优(下) ,更多实操示例请参照视频讲解 。跟着张员外讲编程,学习更轻松,不花钱还能学习真本领 。

推荐阅读