Profiling Python Plugins



  • Maxime pointed me to Profiling Python Plugins.

    However I have problems implementing it.
    I added all the code: import cProfile, def profile(func), def PluginMessage(msg_type, data) and in the Area class

        @profile
        def DrawMsg(self, x1, y1, x2, y2, msg):
    

    Now I get the console message:

        @profile
    NameError: name 'profile' is not defined
    


  • Hi,

    well have you exposed an implementation of the decorator profile like shown in the blog? Here is a small snippet to give you an idea how cProfile works in principal.

    Cheers,
    zipit

    import cProfile
    import math
    import pstats
    
    def some_function():
        """
        """
        profile = cProfile.Profile()
    
        # Start of profiling
        profile.enable()
        data = [math.sqrt(abs(math.sin(i * .001) * math.cos(i * .001)))
                for i in range(100000)]
        profile.disable()
        # End of profiling
    
        stats = pstats.Stats(profile)
        stats.strip_dirs()
        stats.sort_stats("cumtime")
        stats.print_stats()
    
    if __name__ == "__main__":
        some_function()
    
    400002 function calls in 0.060 seconds
    
       Ordered by: cumulative time
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       100000    0.018    0.000    0.018    0.000 {math.cos}
       100000    0.016    0.000    0.016    0.000 {math.sin}
       100000    0.016    0.000    0.016    0.000 {math.sqrt}
       100000    0.008    0.000    0.008    0.000 {abs}
            1    0.003    0.003    0.003    0.003 {range}
            1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    
    [Finished in 0.3s]
    


  • @pim said in Profiling Python Plugins:

    @profile
    def DrawMsg(self, x1, y1, x2, y2, msg):
    

    I thought above should be enough.
    I guess I have to study the blog a bit better.
    Your example seems quite different and I will try it.

    Thanks, Pim



  • Hi,

    my example does nothing terribly unusual (I didn't red the whole blog though). I just gave you an example without the syntactic sugar of a decorator, because I assumed you are maybe a bit confused by it - do not know how decorators work - and therefor struggle to understand how cProfile works (which is not that hard to understand).

    Cheers,
    zipit



  • While the output is not as detailed and neat as with zipit's use of profile, this is what I like to use to measure timing of functions:

    import time
    
    g_timingInfo = ['']
    def timing(f):
        def wrapTiming(*args, **kwargs):
            global g_timingInfo
            time1 = time.clock()
            ret = f(*args, **kwargs)
            time2 = time.clock()
            g_timingInfo.append('T %-8.2f ms : ' % ((time2-time1)*1000.0) + f.func_name)
            return ret
        return wrapTiming
    
    def PrintTiming():
        global g_timingInfo
        if len(g_timingInfo):
            print '\nTIMING INFO:'
            for t in g_timingInfo:
                print t
            print ' '
        else:
            print 'No timing info'
        g_timingInfo = []
    

    In oder to use it, you simply decorate a function (or multiple) with @timing and at a later point of execution you call PrintTiming() to get the accumulated results printed to the Console.
    Like so:

    @timing
    def MyFunction():
        pass
    @timing
    def MySecondFunction():
        pass
    
    def SomewhereInYourCode():
        MyFunction()
        for idx in xrange(100000):
            MyFunction2()
        PrintTiming()
    

    I like the decoration approach, as it's fast to pour some "probes" into your code without modifying the actual implementation of functions.
    Using module inspect you can easily beef it up by adding stack information or nice indentation of results based on call level.
    And this may also give you an idea, how to build decorations yourself. Useful for all kinds of stuff.

    Cheers



  • @pim said in Profiling Python Plugins:

    Maxime pointed me to Profiling Python Plugins.

        @profile
    NameError: name 'profile' is not defined
    

    I guess the issue is written clearly, the profile decorator is not defined. A decorator is nothing more than a function in Python, for more information see Primer on Python Decorators, so to fix your issue, you only have to copy the profile function provided in the Niklas blog post.

    Cheers,
    Maxime.


Log in to reply