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.pycProfile.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中的所有评测回调。无论是从命令行调用探查器还是在脚本中手动调用探查器,都不会影响两个模块之间的时间差。

    事实上,问题的标题具有误导性