I\'m trying to profile an instance method, so I\'ve done something like:
import cProfile
class Test():
def __init__(self):
pass
def method
I was struggling with the same problem and used a wrapper function to get over direct return values. Instead of
cP.runctx("a=foo()", globals(), locales())
I create a wrapper function
def wrapper(b):
b.append(foo())
and profile the call to the wrapper function
b = []
cP.runctx("wrapper(b)", globals(), locals())
a = b[0]
extracting the result of foo's computation from the out param (b) afterwards.
An option for any arbitrary code:
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()
Taken from https://docs.python.org/2/library/profile.html#profile.Profile
I think @detly the .runcall()
is basically the best answer, but for completeness, I just wanted to take @ThomasH 's answer to be function independent:
def wrapper(b, f, *myargs, **mykwargs):
try:
b.append(f(*myargs, **mykwargs))
except TypeError:
print 'bad args passed to func.'
# Example run
def func(a, n):
return n*a + 1
b = []
cProfile.runctx("wrapper(b, func, 3, n=1)", globals(), locals())
a = b[0]
print 'a, ', a
I created a decorator:
import cProfile
import functools
import pstats
def profile(func):
@functools.wraps(func)
def inner(*args, **kwargs):
profiler = cProfile.Profile()
profiler.enable()
try:
retval = func(*args, **kwargs)
finally:
profiler.disable()
with open('profile.out', 'w') as profile_file:
stats = pstats.Stats(profiler, stream=profile_file)
stats.print_stats()
return retval
return inner
Decorate your function or method with it:
@profile
def somefunc(...):
...
Now that function will be profiled.
Alternatively, if you'd like the raw, unprocessed profile data (e.g. because you want to run the excellent graphical viewer RunSnakeRun on it), then:
import cProfile
import functools
import pstats
def profile(func):
@functools.wraps(func)
def inner(*args, **kwargs):
profiler = cProfile.Profile()
profiler.enable()
try:
retval = func(*args, **kwargs)
finally:
profiler.disable()
profiler.dump_stats('profile.out')
return retval
return inner
This is a minor improvement on several of the other answers on this page.
I discovered that you can do this:
prof = cProfile.Profile()
retval = prof.runcall(self.method_actual, *args, **kwargs)
prof.dump_stats(datafn)
The downside is that it's undocumented.