Context Navigation

Profiling Django

Profiling Specific Code

Python has several profiling modules, the least worst of which is the apparently unmaintained ​hotshot. It's better than the Profiler module for our purposes as it has simple 'start' and 'stop' methods, as well as a method that takes a callable and its arguments.

I wrap views and other callables I want to examine in a decorator like this one:

This shows that the culprit is the database commit code; while my queries where fast, actually committing the results to a SQLite database is causing me grief.

You can use ​gather_profile_stats.py in the Django distribution to aggregate the generated profile logs and open them with pstats.Stats.

You can also examine the results with ​KCacheGrind by using it's hotshot2calltree conversion scripts.

Profiling Everything

Middleware

​Profiling Middleware and ​Extended Profiling Middleware print profile results for method, additionally groups results by files and by modules. Add the "&prof=" query parameter and you'll see the profiling results in your browser. Unfortunately, these are both items on Django Snippets, so you should treat them as being untested abandonware, or, more charitably, example code.

There is another unofficial ​profiling middleware, that attaches the profiler stats enclosed by a comment at the bottom of each HTML, XML and JSON document. That is useful in particular when profiling AJAX requests or when you want to watch the actual content and the profiler stats at the same time.

​django-profiling seems to be another variant of the profiling middleware, which declares itself superseded by ​django-logging, which declares itself unmaintained.

Profiling at the server

mod_python

django.core.handlers.profiler-hotshot provides profiling support for Django when using mod_python. TODO: describe how to use this.

Development Server

​django-extensions provides a ​runprofileserver command for running the development server using the hotshot or (c)Profile libraries and provides compatible output for kcachegrind.

A similar solution for the internal development webserver: apply the included patch to django/core/management.py and start Django with manage.py runserver. Each request will create a .prof file in your /tmp directory.

WSGI

An alternative approach to using the built in development server is to run Django from a trivial WSGI server and profile that. For example, using wsgiref: