Project Euler和其他编码竞赛通常有最长的运行时间,或者人们吹嘘他们的特定解决方案运行速度有多快。对于Python,有时方法有些笨拙——即向__main__添加计时代码。
描述Python程序运行时间的好方法是什么?
Project Euler和其他编码竞赛通常有最长的运行时间,或者人们吹嘘他们的特定解决方案运行速度有多快。对于Python,有时方法有些笨拙——即向__main__添加计时代码。
描述Python程序运行时间的好方法是什么?
当前回答
我发现,如果您不想使用命令行选项,该功能快速且易于使用。
要使用,只需在要分析的每个函数上方添加@profile。
def profile(fnc):
"""
Profiles any function in following class just by adding @profile above function
"""
import cProfile, pstats, io
def inner (*args, **kwargs):
pr = cProfile.Profile()
pr.enable()
retval = fnc (*args, **kwargs)
pr.disable()
s = io.StringIO()
sortby = 'cumulative' #Ordered
ps = pstats.Stats(pr,stream=s).strip_dirs().sort_stats(sortby)
n=10 #reduced the list to be monitored
ps.print_stats(n)
#ps.dump_stats("profile.prof")
print(s.getvalue())
return retval
return inner
每个函数的输出如下
Ordered by: cumulative time
List reduced from 38 to 10 due to restriction <10>
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.002 0.002 3151212474.py:37(get_pdf_page_count)
1 0.000 0.000 0.002 0.002 fitz.py:3604(__init__)
1 0.001 0.001 0.001 0.001 {built-in method fitz._fitz.new_Document}
1 0.000 0.000 0.000 0.000 fitz.py:5207(__del__)
1 0.000 0.000 0.000 0.000 {built-in method fitz._fitz.delete_Document}
1 0.000 0.000 0.000 0.000 fitz.py:4816(init_doc)
1 0.000 0.000 0.000 0.000 fitz.py:5197(_reset_page_refs)
1 0.000 0.000 0.000 0.000 fitz.py:4821(<listcomp>)
11 0.000 0.000 0.000 0.000 fitz.py:4054(_getMetadata)
1 0.000 0.000 0.000 0.000 weakref.py:241(values)
其他回答
python wiki是一个用于分析资源的绝佳页面:http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
python文档也是如此:http://docs.python.org/library/profile.html
如Chris Lawlor所示,cProfile是一个很棒的工具,可以很容易地打印到屏幕上:
python -m cProfile -s time mine.py <args>
或存档:
python -m cProfile -o output.file mine.py <args>
PS>如果您使用的是Ubuntu,请确保安装python配置文件
apt-get install python-profiler
如果输出到文件,可以使用以下工具获得良好的可视化效果
PyCallGraph:创建调用图图像的工具安装:
pip install pycallgraph
run:
pycallgraph mine.py args
视图:
gimp pycallgraph.png
你可以使用任何你喜欢的方式来查看png文件,我使用了gimp不幸的是,我经常
dot:graph对于cairo渲染器位图太大。缩放0.257079以适合
这使我的图像变得难以使用。所以我通常创建svg文件:
pycallgraph -f svg -o pycallgraph.svg mine.py <args>
PS>确保安装graphviz(提供点程序):
pip install graphviz
使用gprof2dot通过@maxy/@quodlibetor绘制替代图形:
pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
在Virtaal的源代码中,有一个非常有用的类和装饰器,它可以使分析(甚至对于特定的方法/函数)非常简单。然后可以在KCacheGrind中非常舒适地查看输出。
@Maxy对这个答案的评论对我帮助很大,我认为它应该得到自己的答案:我已经有了cProfile生成的.pstats文件,我不想用pycallgraph重新运行这些文件,所以我使用了gprof2dot,得到了很好的svgs:
$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg
还有BLAM!
它使用点(与pycallgraph使用的相同),因此输出看起来类似。我觉得gprof2dot丢失的信息更少:
我最近创建了金枪鱼,用于可视化Python运行时和导入配置文件;这在这里可能会有所帮助。
使用安装
pip install tuna
创建运行时配置文件
python3 -m cProfile -o program.prof yourfile.py
或导入配置文件(需要Python 3.7+)
python3 -X importprofile yourfile.py 2> import.log
那就把金枪鱼放在档案里
tuna program.prof
我发现cprofiler和其他资源更多地用于优化目的,而不是调试。
我制作了自己的测试模块,用于简单的python脚本速度测试。(在我的例子中,使用ScriptProfilerPy测试了1K+行py文件,并在几分钟内将代码速度提高了10倍。
模块ScriptProfilerPy()将运行代码,并向其添加时间戳。我把模块放在这里:https://github.com/Lucas-BLP/ScriptProfilerPy
Use:
from speed_testpy import ScriptProfilerPy
ScriptProfilerPy("path_to_your_script_to_test.py").Profiler()
输出: