c配置需要很长时间

use*_*541 5 python cprofile

我开始用来cProfile描述我的python脚本.我注意到一些非常奇怪的事情.

当我time用来测量脚本的运行时间时需要4.3秒.

当我使用python -m cProfile script.py它需要7.3秒.

在代码中运行探查器时:

import profile
profile.run('main()')
Run Code Online (Sandbox Code Playgroud)

需要63秒!!

我可以理解为什么加分析时,它可能需要更多一点时间,但为什么会出现使用之间的这种差异cProfile来自外部或代码的一部分?我使用这么多时间有原因profile.run吗?

skr*_*sme 6

奇怪的是,你所看到的是预期的行为.在Python文档的概要分析部分的介绍中,它指出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()')
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

并使用分析器调用它:

python -m profile test_script.py

报告主要运行1.662秒.

python -m cProfile test_script.py

报告主要运行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代码文件.来源可以在这里查看.
  3. 所述Profileprofile.py不从任何其他类(线111)继承,而Profile在类cProfile.py(线66)继承_lsprof.Profiler,这是C源文件中实现.

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

另外,您可以profile通过校准来提高性能.文档提供了有关如何执行此操作的详细信息有关如何/为何所有这些内容的更多详细信息,请参阅有关确定性分析限制的Python文档部分.

TL; DR

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