CherryPy Project Download

Cachegrind

There are cachegrind viewers for most OS's: Unix, Windows and OSX. In addition, there is a tool for converting from cProfile output to cachegrind output: http://www.gnome.org/~johan/lsprofcalltree.py ...

Cachegrind output can be viewed nicely: http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindShot3 to discover where the most time is being spent.

Typically one would wrap the call of a particular function to obtain the output, or you can use the tool I built once it makes it to trunk.

import cherrypy

import cProfile
import lsprofcalltree

#-------------------------------------------------------------------------------
class CachegrindHandler(cherrypy.dispatch.LateParamPageHandler):
    """Callable which profiles the subsequent handlers and outputs cachegrind files."""
        
    def __init__(self, next_handler):
        self.next_handler = next_handler
 
    def __call__(self):
        """ 
        Profile this request and output results in a cachegrind compatible format.
        """ 
        try:
            p = cProfile.Profile()
            p.runctx('self._real_call()', globals(), locals())
        finally:
            count = 1 
            filename = None
            path = cherrypy.request.path_info.strip("/").replace("/", "_")
            script = cherrypy.request.app.script_name.strip("/").replace("/", "_")
            path = path + "_" + script
            while not filename or os.path.exists(filename):
                filename = os.path.join(thisdir,"cachegrind.out.%s_%d" % (path, count))
                count += 1
            print "writing profile output to %s" % filename
            k = lsprofcalltree.KCacheGrind(p)
            data = open(filename, 'w+')
            k.output(data)
            data.close()
        return self.result

    def _real_call(self):
        """Call the next handler and store its result."""
        self.result = self.next_handler()


def cachegrind():
    """A CherryPy 3 Tool for loading Profiling requests."""
    cherrypy.request.handler = CachegrindHandler(cherrypy.request.handler)

# Priority of 100 is meant to ensure that this tool runs later than all others, such that 
# CachegrindHandler wraps all other handlers and therefore can profile them along with
# the controller.
cherrypy.tools.cachegrind = cherrypy.Tool('before_handler', cachegrind, priority=100)

cherrypy._cpconfig.environments['production']['tools.cachegrind.on'] = False
cherrypy._cpconfig.environments['staging']['tools.cachegrind.on'] = True
cherrypy._cpconfig.environments['development']['tools.cachegrind.on'] = True

Hosted by WebFaction

Log in as guest/cherrypy to create/edit wiki pages