分析存在于运行时中间的代码
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 可以处理的情况下使用它也会很有趣。它为您处理现有案例并具有漂亮的界面:)
【讨论】:
以上是关于分析存在于运行时中间的代码的主要内容,如果未能解决你的问题,请参考以下文章