High Performance Django
High Performance Django
David Cramer
http://www.davidcramer.net/
http://www.ibegin.com/
Curse
• Peak daily traffic of approx. 15m pages, 150m hits.
• Profiling
Tools of the Trade
• Webserver (Apache, Nginx, Lighttpd)
class Poll(models.Model):
name = models.CharField()
category = models.ForeignKey(Category)
created_by = models.ForeignKey(User)
def a_bad_example(request):
# We have just caused Poll to JOIN with User and Category,
# which will also JOIN with User a second time.
my_polls = Poll.objects.all().select_related()
return render_to_response('polls.html', locals(), request)
def a_good_example(request):
# Use select_related explicitly in each case.
poll = Poll.objects.all().select_related('category')
return render_to_response('polls.html', locals(), request)
Template Rendering
• Sandboxed engines are typically slower by nature.
• Use a reverse proxy in between the browser and your web servers:
• For typical web apps you can serve the same cached page
# Now that we are caching the object list we are going to want to invalidate it
class MyModel(models.Model):
name = models.CharField()
class ProfilerMiddleware(object):
def can(self, request):
return settings.DEBUG and 'prof' in request.GET and (not settings.INTERNAL_IPS or request.META['REMOTE_ADDR'] in
settings.INTERNAL_IPS)
def process_view(self, request, callback, callback_args, callback_kwargs):
if self.can(request):
self.profiler = profile.Profile()
args = (request,) + callback_args
return self.profiler.runcall(callback, *args, **callback_kwargs)
def process_response(self, request, response):
if self.can(request):
self.profiler.create_stats()
out = StringIO()
old_stdout, sys.stdout = sys.stdout, out
self.profiler.print_stats(1)
sys.stdout = old_stdout
response.content = '<pre>%s</pre>' % out.getvalue()
return response
http://localhost:8000/?prof
Profiling Database Queries
from django.db import connection
class DatabaseProfilerMiddleware(object):
def can(self, request):
return settings.DEBUG and 'dbprof' in request.GET \
and (not settings.INTERNAL_IPS or \
request.META['REMOTE_ADDR'] in settings.INTERNAL_IPS)
server software.
Thanks!