我想使用 cProfile 在 Python 中分析一个函数的方法。我尝试了以下方法:
import cProfile as profile
# Inside the class method...
profile.run("self.myMethod()", "output_file")
但它不起作用。如何用“运行”调用 self.method?
编辑:对不起,没有意识到配置文件调用是在类方法中。
run
只是尝试exec
传递给它的字符串。如果self
未绑定到您正在使用的分析器范围内的任何内容,则不能在run
! 使用该runctx
方法将调用范围内的局部和全局变量传递给分析器:
>>> import time
>>> import cProfile as profile
>>> class Foo(object):
... def bar(self):
... profile.runctx('self.baz()', globals(), locals())
...
... def baz(self):
... time.sleep(1)
... print 'slept'
... time.sleep(2)
...
>>> foo = Foo()
>>> foo.bar()
slept
5 function calls in 2.999 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.999 2.999 <stdin>:5(baz)
1 0.000 0.000 2.999 2.999 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
2 2.999 1.499 2.999 1.499 {time.sleep}
注意最后一行:time.sleep
是什么占用了时间。
使用 profilehooks 装饰器
如果配置文件下的函数返回值,则需要稍微更改 @katrielalex 的出色答案:
... profile.runctx('val = self.baz()', globals(), locals())
... print locals()['val']
import cProfile
p = cProfile.Profile()
p.runcall(self.myMethod)
p.print_stats()
该类Profile
记录在这里。
我不建议分析单个例程,因为这意味着提前知道那里存在问题。
性能问题的一个基本方面是它们是偷偷摸摸的。它们不在您认为的位置,因为如果它们是您已经解决了它们。
最好以实际工作负载运行整个程序,并让分析技术告诉您问题出在哪里。
这是一个分析发现问题的示例,但不是预期的。