Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to profile a Django custom management command exclusively

I would like to profile a custom management command that is relatively CPU intensive (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?

like image 470
muhuk Avatar asked Nov 06 '09 11:11

muhuk


People also ask

How do I run a custom command in Django?

The Python file that contains the code for the custom command is nested inside several directories: At the root level of the Django app, create a directory called management. Within management create a commands directory. Within commands create a file named something similar to print_book_titles.py .

Can we create Django project using manage py command?

In addition, manage.py is automatically created in each Django project. It does the same thing as django-admin but also sets the DJANGO_SETTINGS_MODULE environment variable so that it points to your project's settings.py file.

What is Django profiling?

django-profiler is util for profiling python code mainly in django projects but can be used also on ordinary python code. It counts sql queries a measures time of code execution. It logs its output via standard python logging library and uses logger profiling .


2 Answers

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.

like image 95
Carl Meyer Avatar answered Oct 19 '22 17:10

Carl Meyer


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.

like image 19
muhuk Avatar answered Oct 19 '22 19:10

muhuk