Return value while using cProfile

后端 未结 5 541
难免孤独
难免孤独 2020-12-13 06:59

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

import cProfile

class Test():

    def __init__(self):
        pass

    def method         


        
相关标签:
5条回答
  • 2020-12-13 07:27

    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.

    0 讨论(0)
  • 2020-12-13 07:36

    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

    0 讨论(0)
  • 2020-12-13 07:37

    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
    
    0 讨论(0)
  • 2020-12-13 07:47

    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.

    0 讨论(0)
  • 2020-12-13 07:50

    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.

    0 讨论(0)
提交回复
热议问题