使用cProfile时返回值

28 投票
5 回答
12299 浏览
提问于 2025-04-15 15:09

我正在尝试对一个实例方法进行性能分析,所以我做了类似这样的事情:

import cProfile

class Test():

    def __init__(self):
        pass

    def method(self):
        cProfile.runctx("self.method_actual()", globals(), locals())

    def method_actual(self):
        print "Run"

if __name__ == "__main__":
    Test().method()

但是现在出现了问题,我希望“method”能够返回由“method_actual”计算得出的值。我其实不想让“method_actual”被调用两次。

有没有其他的方法可以做到这一点,而且还要线程安全?(在我的应用中,cProfile的数据会保存到以某个参数命名的数据文件中,这样它们就不会被覆盖,我可以在之后合并这些数据。)

5 个回答

8

我之前也遇到过同样的问题,所以我用了一个包装函数来解决直接返回值的问题。不是直接这样做:

cP.runctx("a=foo()", globals(), locales())

我创建了一个包装函数

def wrapper(b):
  b.append(foo())

然后对这个包装函数的调用进行分析

b = []
cP.runctx("wrapper(b)", globals(), locals())
a = b[0]

最后从输出参数(b)中提取出 foo 计算的结果。

31

这是一个可以用来处理任何任意代码的选项:

import cProfile, pstats, sys
pr = cProfile.Profile()
pr.enable()

my_return_val = my_func(my_arg)

pr.disable()
ps = pstats.Stats(pr, stream=sys.stdout)
ps.print_stats()

内容来自 https://docs.python.org/2/library/profile.html#profile.Profile

37

我发现你可以这样做:

prof = cProfile.Profile()
retval = prof.runcall(self.method_actual, *args, **kwargs)
prof.dump_stats(datafn)

不过缺点是,这个方法没有官方文档说明。

撰写回答