Granular Profiling in PyCharm

By Eric — 1 minute read

PyCharm added profiler integration in version 4.5, which I thought was pretty cool. Used as documented, though, it hasn't been terribly useful. Here's a way to improve on that.

In my case, I was interested in profiling a web service -- specifically requests to a particular resource. I started up the server application using the profiler button on the toolbar, made a request to that resource, took a snapshot and prepared to analyze some data. Unfortunately, the profiler didn't think the request handler code was even worth including in the call graph since it didn't take enough time. Boo.

But... PyCharm can actually open any profiler snapshot made with cProfile. A blog post I had read suggested making a decorator for profiling, so I wrote this:

import cProfile
import functools
import os


def profile(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        profiler = cProfile.Profile()
        try:
            profiler.enable()
            ret = func(*args, **kwargs)
            profiler.disable()
            return ret
        finally:
            filename = os.path.expanduser(
                os.path.join('~', func.__name__ + '.pstat')
            )
            profiler.dump_stats(filename)
    return wrapper

Put this decorator on a function, and it will create a .pstat file in your home directory named after the function it decorates. For example:

@profile
def handle_get(request):
    # etc.

After running the function, there would be a handle_get.pstat file in my home directory.

Now I can use Tools | Open CProfile snapshot in PyCharm and analyze timings and the call graph just for the function that I'm interested in.