How to profile a Django custom management command exclusively
I would like to profile a custom management command that is relatively CPU intens开发者_Go百科ive (renders an image using PIL). When I use the following command I get all sorts of Django modules (admin, ORM etc) in my profiling results:
python -m cProfile manage.py testrender
I have removed all imports that can potentially import Django but I am guessing the following is the culprit:
from django.core.management.base import BaseCommand, CommandError
Is there a way to filter out cProfile
results? (only filenames are shown, no paths) Or, is there any other way to exclude/include respective modules/packages from profiling?
I solved this problem the following way:
from cProfile import Profile
from django.core.management.base import BaseCommand
class Command(BaseCommand):
...
def _handle(self, *args, **options):
# Actual code I want to profile
pass
def handle(self, *args, **options):
if options['profile']:
profiler = Profile()
profiler.runcall(self._handle, *args, **options)
profiler.print_stats()
else:
self._handle(*args, **options)
This way profiling statistics are gathered within the scope of _handle
. So instead of:
python -m cProfile manage.py testrender
I'll have to run:
python manage.py testrender --profile
which is even better.
Separate the PIL functionality into its own function/class in its own module, and import it from your management command. Then you can test/profile the PIL functionality independently of Django.
If I can't find any answers. Gprof2Dot as explained here can be an acceptable hack.
It doesn't filter out modules I'm not interested, but hopefully it will make it easier to inspect the results visually seperating my code and Django modules.
精彩评论