【问题标题】:cProfile taking a very long timecProfile 需要很长时间
【发布时间】:2014-10-09 03:38:47
【问题描述】:

我开始使用cProfile 来分析我的python 脚本。 我注意到一些很奇怪的事情。

当我使用time 测量脚本的运行时间时,需要 4.3 秒。

当我使用python -m cProfile script.py 时,需要 7.3 秒。

在代码中运行分析器时:

import profile
profile.run('main()')

需要 63 秒!!

我可以理解为什么在添加分析时可能需要更多时间,但为什么从外部使用 cProfile 或作为代码的一部分使用会有如此大的区别? 我使用profile.run 需要这么长时间是有原因的吗?

【问题讨论】:

    标签: python cprofile


    【解决方案1】:

    奇怪的是,您看到的是预期行为。在 Python 文档的 introduction to the profilers 部分中,它指出与 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 配置文件 test_script.py

    报告 main 运行 1.662 秒。

    python -m cProfile test_script.py

    报告 main 运行 0.143 秒。

    这表明您启动分析器的方式与您在cProfileprofile 之间看到的差异无关。不同之处在于两个分析器如何处理“事件”,例如函数调用或返回。在这两种情况下,执行代码中都有软件挂钩,它们会触发回调以跟踪这些事件并执行诸如更新事件计数器和启动或停止计时器之类的操作。然而,profile 模块在 Python 中本地处理所有这些事件,这意味着您的解释器必须离开您的代码,执行回调内容,然后返回以继续您的代码。

    cProfile 也必须发生同样的事情(执行分析回调),但它更快,因为回调是用 C 编写的。查看两个模块文件 profile.pycProfile.py 展示了一些差异:

    1. profile.py 是 610 行,而 cProfile.py 只有 199 行 - 它的大部分功能都在 C 中处理。
    2. profile.py 主要使用 Python 库,而 cProfile.py 导入“_lsprof”,一个 C 代码文件。源码可以查看here
    3. profile.py 中的Profile 类不继承自任何其他类(第 111 行),而 cProfile.py 中的Profile 类(第 66 行)继承自 _lsprof.Profiler,在 C 源文件中实现。

    正如文档所述,cProfile 通常是要走的路,因为它主要是用 C 实现的,所以一切都更快。

    顺便说一句,您可以通过校准来提高profile 的性能。有关如何做到这一点的详细信息available in the docs 还有更多有关如何/为什么所有这些东西的详细信息,请参见Deterministic Profilinglimitations 的 Python 文档部分。

    TL;DR

    cProfile 更快,因为正如它的名字所暗示的,它的大部分是用 C 实现的。这与 profile 模块形成对比,它必须处理本机 Python 中的所有分析回调。无论您是从命令行调用分析器还是在脚本中手动调用分析器,都不会影响两个模块之间的时间差。

    【讨论】:

    • 其实题主有误导性
    猜你喜欢
    • 2013-09-07
    • 2020-08-26
    • 2012-11-26
    • 2019-12-27
    • 2017-10-22
    • 2020-11-15
    • 2016-05-19
    • 2011-11-20
    • 2011-12-19
    相关资源
    最近更新 更多