Python cProfile需要很长时间
我开始使用Python cProfile需要很长时间,python,cprofile,Python,Cprofile,我开始使用cProfile来分析我的python脚本。 我注意到一些非常奇怪的事情 使用time测量脚本的运行时间需要4.3秒 当我使用python-mcprofile script.py时,需要7.3秒 在代码中运行探查器时: import profile profile.run('main()') 这需要63秒 我可以理解为什么在添加分析时可能需要更多的时间,但是为什么从外部使用cProfile或作为代码的一部分使用两者之间存在如此大的差异? 当我使用profile.run时,会花费这么多
cProfile
来分析我的python脚本。
我注意到一些非常奇怪的事情
使用time
测量脚本的运行时间需要4.3秒
当我使用python-mcprofile script.py时,需要7.3秒
在代码中运行探查器时:
import profile
profile.run('main()')
这需要63秒
我可以理解为什么在添加分析时可能需要更多的时间,但是为什么从外部使用cProfile
或作为代码的一部分使用两者之间存在如此大的差异?
当我使用profile.run
时,会花费这么多时间,这有什么原因吗?奇怪的是,你看到的是预期的行为。在Python文档的一节中,它指出与cProfile
相比,profile
增加了“分析程序的显著开销”。你所看到的区别在于你所使用的库,而不是你如何调用它们。考虑这个脚本:
import profile
import cProfile
def nothing():
return
def main():
for i in xrange(1000):
for j in xrange(1000):
nothing()
return
cProfile.run('main()')
profile.run('main()')
cProfile
的输出显示main运行大约需要0.143秒,而profile
变量报告的运行时间为1.645秒,约为11.5倍
现在,让我们再次将脚本更改为:
def nothing():
return
def main():
for i in xrange(1000):
for j in xrange(1000):
nothing()
return
if __name__ == "__main__":
main()
并使用探查器将其称为:
python-m profile test_script.py
报告运行main的时间为1.662秒
python-mcprofile test_script.py
报告运行main的时间为0.143秒
这表明启动探查器的方式与您看到的cProfile
和profile
之间的差异无关。这种差异是由两个探查器处理“事件”(如函数调用或返回)的方式造成的。在这两种情况下,执行代码中都有软件钩子,它们触发回调以跟踪这些事件,并执行诸如更新事件计数器和启动或停止计时器之类的操作。但是,profile
模块在Python中以本机方式处理所有这些事件,这意味着您的解释器必须离开您的代码,执行回调,然后返回继续您的代码
同样的事情也会发生在cProfile
(执行分析回调),但是速度要快得多,因为回调是用C编写的。查看两个模块文件profile.py和cProfile.py可以看出一些不同:
profile.py是610行,而cProfile.py只有199行-它的大部分函数都是用C处理的
profile.py主要利用Python库,而cProfile.py导入C代码文件“\u lsprof”。可以查看源代码
Profile.py中的Profile
类不继承任何其他类(第111行),而cProfile.py中的Profile
类(第66行)继承自\u lsprof.Profiler
,后者在C源文件中实现
正如docs所说,cProfile
通常是一种方法,因为它主要是用C实现的,所以一切都更快
另外,您可以通过校准profile
来提高其性能。关于如何做到这一点的详细信息在和的Python文档部分中有更多关于如何/为什么所有这些东西都是这样的详细信息
TL;博士
cProfile
要快得多,因为顾名思义,它大部分是用C实现的。这与profile
模块形成对比,后者必须处理本机Python中的所有评测回调。无论是从命令行调用探查器还是在脚本中手动调用探查器,都不会影响两个模块之间的时间差。事实上,问题的标题具有误导性