I have a C++ library that I am wrapping and exposing via python. For various reasons I need to overload the __call__ of the functions when exposing them via python.
A minimal example is below using time.sleep to mimic functions with various compute times
import sys import time class Wrap_Func(object): def __init__(self, func, name): self.name = name self.func = func def __call__(self, *args, **kwargs): # do stuff return self.func(*args, **kwargs) def wrap_funcs(): thismodule = sys.modules[__name__] for i in range(3): fname = 'example{}'.format(i) setattr(thismodule, fname, Wrap_Func(lambda: time.sleep(i), fname)) wrap_funcs() When profiling my code via cProfile I get a list of __call__ routines. I am unable to ascertain which routines are taking the majority of the compute time.
>>> import cProfile >>> cProfile.runctx('example0(); example1(); example2()', globals(), locals()) 11 function calls in 6.000 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 3 0.000 0.000 6.000 2.000 <ipython-input-48-e8126c5f6ea3>:11(__call__) 3 0.000 0.000 6.000 2.000 <ipython-input-48-e8126c5f6ea3>:20(<lambda>) 1 0.000 0.000 6.000 6.000 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 3 6.000 2.000 6.000 2.000 {time.sleep} Expected
By manually defining the functions (this needs to be dynamic and wrapper as above) as
def example0(): time.sleep(0) def example1(): time.sleep(1) def example2(): time.sleep(2) I get the expected output of
>>> import cProfile >>> cProfile.runctx('example0(); example1(); example2()', globals(), locals()) 11 function calls in 6.000 seconds 8 function calls in 3.000 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 <ipython-input-58-688d247cb941>:1(example0) 1 0.000 0.000 0.999 0.999 <ipython-input-58-688d247cb941>:4(example1) 1 0.000 0.000 2.000 2.000 <ipython-input-58-688d247cb941>:7(example2) 1 0.000 0.000 3.000 3.000 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 3 3.000 1.000 3.000 1.000 {time.sleep}
cProfile.Profiler.snapshot_statsit appears as though the root of the problem is the__call__.func_code.co_name