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)

