分析存在于运行时中间的代码

Posted

技术标签:

【中文标题】分析存在于运行时中间的代码【英文标题】:Profiling a code which exists in the middle of runtime 【发布时间】:2020-11-09 15:44:16 【问题描述】:

我正在尝试使用 cProfile 分析函数的运行时。

import cProfile
import pstats
import time

def foo(n):
    time.sleep(2)
    res = 0
    exit()
    for i in range(100000):
        res = res *1024+res



with cProfile.Profile() as pr:
    foo(n=1)  

pr.dump_stats('my_data.dat')


with open("my_data.dat","w") as f:
    p = pstats.Stats("my_data.dat",stream=f)
    p.print_stats()

注意我在函数中间退出,

有没有办法配置一个分析器,它会在 Kill 信号上将累积的结果保存到某个文件中?

AFAIK 转储仅在 函数成功运行之后发生。

我这样做是因为我正在分析一个性能问题,该函数需要很长时间才能运行,并且需要找到一种方法来运行它,以便找到瓶颈。

我不能等到函数完成,因为它可能需要几个小时。

谢谢,

【问题讨论】:

【参考方案1】:

嗯,有多种方法可以做到这一点。

首先,我需要指出,cProfile 不会在您当前的foo 函数中为您提供帮助,因为 cProfile 的最小单位是函数。当然我会假设你的实际代码比这复杂得多,并且实际上有多个函数条目。

所以,对于解决方案。

atexit 是一个有用的内置库来处理这种情况。你可以这样做

import atexit
@atexit.register
def your_exit_routine():
    # stuff you want to run before exiting

如果您通过exit() 退出,atexit 将起作用。在某些其他情况下它可能不起作用。

您也可以尝试signal 模块,它处理系统信号,例如 SIGKILL 或 SIGTERM。

import signal
signal.signal(signal.SIGTERM, your_exit_routine)

当您使用 CTRL+C 发送 SIGTERM 信号时,这非常方便。

但是,当涉及到多线程或多进程时,它变得更加复杂。在这种情况下,我会推荐使用viztracer,它支持多线程和多进程,并且可以可视化您的程序。

实际上,即使在 cProfile 可以处理的情况下使用它也会很有趣。它为您处理现有案例并具有漂亮的界面:)

【讨论】:

以上是关于分析存在于运行时中间的代码的主要内容,如果未能解决你的问题,请参考以下文章

Windows 运行时中的内存管理

单击按钮时中止正在运行的功能

如何解决android studio 运行时中文乱码的问题

c#当sql视图不存在时中断

访问 2010 运行时中的访问 2003 应用程序运行时错误

混合模式程序集是针对运行时的“2.0.50727”版本构建的,无法在 4.0 运行时中加载