我开始使用cProfile来分析我的python脚本。我注意到了一些很奇怪的事情。
当我使用time来测量脚本的运行时间时,需要4.3秒。
当我使用python -m cProfile script.py时,它需要7.3秒。
在代码中运行分析器时:
import profile
profile.run('main()')它需要63秒!
我可以理解为什么在添加分析时可能需要更多的时间,但是为什么从外部使用cProfile与将其作为代码的一部分有这么大的区别呢?我使用profile.run需要这么多时间,有什么原因吗?
发布于 2014-08-15 21:41:42
奇怪的是,你看到的是预期的行为。在Python的introduction to the profilers部分中,它指出profile与cProfile相比增加了“配置程序的大量开销”。你所看到的不同之处在于你所使用的库,而不是你如何称呼它们。考虑一下这个脚本:
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配置文件test_script.py
报告为main运行的1.662秒。
python -m cProfile test_script.py
报告为main运行的0.143秒。
这表明,您启动分析器的方式与您看到的cProfile和profile之间的差异无关。造成这种差异的原因是两个分析器如何处理函数调用或返回等“事件”。在这两种情况下,您的执行代码中都有软件钩子,它们触发回调以跟踪这些事件,并执行诸如事件的更新计数器和启动或停止定时器等操作。但是,profile模块本机处理所有这些事件,这意味着您的解释器必须离开您的代码,执行回调内容,然后返回以继续您的代码。
同样的事情必须发生在cProfile (执行分析回调)上,但速度要快得多,因为回调是用C编写的。看看两个模块文件profile.py和cProfile.py展示了一些不同之处:
Profile类在profile.py中不继承任何其他类(第111行),而cProfile.py中的Profile类(第66行)从_lsprof.Profiler继承,后者在C源文件中实现。作为docs状态,cProfile通常是要走的路,因为它主要是用C实现的,所以一切都更快。
顺便说一下,您可以通过校准profile来提高它的性能。关于如何实现available in the docs的详细信息--在Deterministic Profiling和limitations的Python部分中,有更多关于这些内容是如何/为什么是这样的详细信息。
TL;DR
cProfile要快得多,因为顾名思义,大部分是用C实现的。这与profile模块不同,后者必须处理本机Python中的所有分析回调。无论是从命令行调用分析器,还是在脚本中手动调用,都不会影响这两个模块之间的时间差。
https://stackoverflow.com/questions/25325788
复制相似问题