百科狗-知识改变命运!
--

Python性能分析

百变鹏仔1年前 (2023-11-21)阅读数 13#技术干货
文章标签注释

python标准库提供两个代码性能分析相关的模块,即timeit和cProfile/profile。前者更适合测试简短的代码片段,后者则可分析代码片段乃至整体模块中各个函数的调用次数、运行耗时等信息。

cProfile是profile的C版本,开销更小。基于cProfile模块,可方便地评估程序性能瓶颈(bottleneck),借以发现程序中值得优化的短板。

根据粒度不同,可将cProfile使用场景分为三类。

1.1分析单条语句

importcProfile,pstats,re,cStringIO

cProfile.run('re.compile("foo|bar")','prfRes')#将cProfile的结果写入prfRes文件

p=pstats.Stats('prfRes')#pstats读取cProfile输出结果

#strip_dirs()剥除模块名的无关路径(如C:\Python27\lib\)

#sort_stats('cumtime')或sort_stats('cumulative')按照cumtime对打印项排序

#print_stats(n)打印输出前10行统计项(不指定n则打印所有项)

p.strip_dirs().sort_stats('cumtime').print_stats(5)

pstats模块可用多种方式对cProfile性能分析结果进行排序并输出。运行结果如下:

TueMay2413:56:072016prfRes

195functioncalls(190primitivecalls)in0.001seconds

Orderedby:cumulativetime

Listreducedfrom33to5duetorestriction

ncallstottimepercallcumtimepercallfilename:lineno(function)

10.0000.0000.0010.001:1()

10.0000.0000.0010.001re.py:192(compile)

10.0000.0000.0010.001re.py:230(_compile)

10.0000.0000.0010.001sre_compile.py:567(compile)

10.0000.0000.0000.000sre_compile.py:552(_code)

其中,tottime表示某函数的总计运行时间(不含该函数内调用的子函数运行时间),cumtime表示某函数及其调用的子函数的累积运行时间。

1.2分析代码片段

pr=cProfile.Profile()

pr.enable()#以下为待分析代码段

regMatch=re.match('^([^/]*)/(/|\*)+(.*)$','//*suspicious')

printregMatch.groups()

pr.disable()#以上为待分析代码段

s=cStringIO.StringIO()

pstats.Stats(pr,stream=s).sort_stats('cumulative').print_stats(10)

prints.getvalue()

运行结果如下:

('','*','suspicious')

536functioncalls(512primitivecalls)in0.011seconds

Orderedby:cumulativetime

Listreducedfrom78to10duetorestriction

ncallstottimepercallcumtimepercallfilename:lineno(function)

20.0000.0000.0090.005C:\Python27\lib\idlelib\PyShell.py:1343(write)

20.0000.0000.0090.005C:\Python27\lib\idlelib\rpc.py:591(__call__)

20.0000.0000.0090.005C:\Python27\lib\idlelib\rpc.py:208(remotecall)

20.0000.0000.0090.004C:\Python27\lib\idlelib\rpc.py:238(asyncreturn)

20.0000.0000.0090.004C:\Python27\lib\idlelib\rpc.py:279(getresponse)

20.0000.0000.0090.004C:\Python27\lib\idlelib\rpc.py:295(_getresponse)

20.0000.0000.0090.004C:\Python27\lib\threading.py:309(wait)

80.0090.0010.0090.001{method'acquire'of'thread.lock'objects}

10.0000.0000.0020.002C:\Python27\lib\re.py:138(match)

10.0000.0000.0020.002C:\Python27\lib\re.py:230(_compile)

1.3分析整个模块

使用命令行,调用cProfile脚本分析其他脚本文件。命令格式为:

python-mcProfile[-ooutput_file][-ssort_order]myscript.py

注意,-o和-s选项不可同时使用。

以C代码统计工具为例,运行如下命令:

E:\PyTest>python-mcProfile-stottimeCLineCounter.pysource-d-b>out.txt

截取out.txt文件部分内容如下:

250316245433620.25xtm_mgr.c

1408729374932093169380.26

762068functioncalls(762004primitivecalls)in2.967seconds

Orderedby:internaltime

ncallstottimepercallcumtimepercallfilename:lineno(function)

Python性能分析

820.9850.0122.8690.035CLineCounter.py:11(CalcLines)

1176400.6120.0001.3150.000re.py:138(match)

1176500.3810.0000.3810.000{method'match'of'_sre.SRE_Pattern'objects}

1176550.3190.0000.3240.000re.py:230(_compile)

1380500.1980.0000.1980.000{method'isspace'of'str'objects}

1058230.1650.0000.1650.000{method'strip'of'str'objects}

123156/1231410.1540.0000.1540.000{len}

378870.0550.0000.0550.000{method'group'of'_sre.SRE_Match'objects}

820.0410.0000.0410.000{method'readlines'of'file'objects}

820.0160.0000.0160.000{open}

10.0040.0042.9502.950CLineCounter.py:154(CountDir)

由tottime可见,此处的性能瓶颈在于CalcLines()函数和其中的正则表达式处理。而isspace()和strip()方法及len()函数因调用次数较多,总的耗时也颇为可观。

作为对比,以下给出一种未使用正则表达式的统计实现:

defCalcLines(line,isBlockComment):

lineType,lineLen=0,len(line)

line=line+'\n'#添加一个字符防止iChar+1时越界

iChar,isLineComment=0,False

whileiChar

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)