tags:

views:

167

answers:

2

I'm trying to profile an instance method, so I've done something like:

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()

But now problems arise when I want "method" to return a value that is computed by "method_actual". I don't really want to call "method_actual" twice.

Is there another way, something that can be thread safe? (In my application, the cProfile data are saved to datafiles named by one of the args, so they don't get clobbered and I can combine them later.)

+4  A: 

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.

detly
+1  A: 

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(), locales())
a = b[0]

extracting the result of foo's computation from the out param (b) afterwards.

ThomasH