Производительность и оптимизация

В этом документе представлен обзор методов и инструментов, которые могут помочь сделать ваш код Django более эффективным - быстрее и с меньшим использованием системных ресурсов.

Введение

Обычно первое, что нужно сделать, это написать работающий код , логические функции которого должны обеспечивать ожидаемый результат. Однако иногда этого бывает недостаточно для того, чтобы код работал так эффективно, как хотелось бы.

В этом случае нужно что-то - а на практике часто набор вещей - для улучшения производительности кода без или минимально влияя на его поведение.

Общие подходы

Что вы оптимизации для ?

Важно иметь четкое представление о том, что вы подразумеваете под «производительностью». Это не одна метрика.

Повышение скорости может быть наиболее очевидной целью для программы, но иногда могут потребоваться другие улучшения производительности, такие как меньшее потребление памяти или меньшие требования к базе данных или сети.

Улучшения в одной области часто приводят к повышению производительности в другой, но не всегда; иногда один может быть даже за счет другого. Например, повышение скорости работы программы может привести к тому, что она будет использовать больше памяти. Хуже того, это может быть обреченным на провал - если повышение скорости настолько требует памяти, что системе начинает не хватать памяти, вы принесете больше вреда, чем пользы.

Следует иметь в виду и другие компромиссы. Ваше собственное время - ценный ресурс, более ценный, чем время процессора. Некоторые улучшения могут оказаться слишком сложными для реализации или могут повлиять на переносимость или ремонтопригодность кода. Не все улучшения производительности стоят затраченных усилий.

Итак, вам нужно знать, к каким улучшениям производительности вы стремитесь, и вам также необходимо знать, что у вас есть веская причина для того, чтобы стремиться в этом направлении - и для этого вам необходимо:

Тестирование производительности

Бесполезно просто гадать или предполагать, в чем заключается неэффективность вашего кода.

Инструменты Django

django-debug-toolbar - очень удобный инструмент, который дает представление о том, что делает ваш код и сколько времени он тратит на это. В частности, он может показать вам все SQL-запросы, которые генерирует ваша страница, и сколько времени на каждый из них потребовалось.

Для панели инструментов также доступны сторонние панели, которые могут (например) сообщать о производительности кеша и времени отрисовки шаблонов.

Сторонние сервисы

Существует ряд бесплатных сервисов, которые будут анализировать и составлять отчеты о производительности страниц вашего сайта с точки зрения удаленного HTTP-клиента, фактически имитируя опыт реального пользователя.

Они не могут сообщить о внутреннем устройстве вашего кода, но могут дать полезную информацию об общей производительности вашего сайта, включая аспекты, которые невозможно адекватно измерить в среде Django. Примеры включают:

Есть также несколько платных сервисов, которые выполняют аналогичный анализ, в том числе те, которые поддерживают Django и могут интегрироваться с вашей кодовой базой для более полного профилирования его производительности.

Сделайте все правильно с самого начала

Некоторая работа по оптимизации включает в себя устранение недостатков производительности, но часть работы может быть встроена в то, что вы в любом случае будете делать, как часть передовых методов, которые вам следует принять еще до того, как вы начнете думать об улучшении производительности.

В этом отношении Python - отличный язык для работы, потому что решения, которые выглядят элегантно и кажутся правильными, обычно являются наиболее эффективными. Как и в случае с большинством других навыков, изучение того, что «выглядит правильно», требует практики, но одним из наиболее полезных советов является:

Работаем на соответствующем уровне

Django предлагает множество разных подходов к вещам, но то, что что-то можно делать определенным образом, не означает, что это наиболее подходящий способ. Например, вы можете обнаружить, что можете рассчитать одно и то же - количество элементов в коллекции, возможно, - в a QuerySet, Python или шаблоне.

Однако почти всегда будет быстрее выполнить эту работу на более низком, чем на более высоком уровне. На более высоких уровнях система должна иметь дело с объектами через несколько уровней абстракции и уровни машинного оборудования.

То есть база данных обычно может делать что-то быстрее, чем Python, который может делать это быстрее, чем язык шаблонов:

# QuerySet operation on the database
# fast, because that's what databases are good at
my_bicycles.count()

# counting Python objects
# slower, because it requires a database query anyway, and processing
# of the Python objects
len(my_bicycles)

# Django template filter
# slower still, because it will have to count them in Python anyway,
# and because of template language overheads
{{ my_bicycles|length }}

Вообще говоря, наиболее подходящий уровень для работы - это самый низкий уровень, для которого удобно писать код.

Примечание

Приведенный выше пример носит исключительно иллюстративный характер.

Во-первых, в реальной жизни вам нужно подумать о том, что происходит до и после вашего подсчета, чтобы решить, как это сделать оптимальным образом в данном конкретном контексте . В документах по оптимизации базы данных описан случай, когда подсчет в шаблоне был бы лучше .

Во-вторых, есть и другие варианты, которые следует учитывать: в реальной жизни метод , который вызывает метод непосредственно из шаблона, может быть наиболее подходящим выбором.{{ my_bicycles.count }}QuerySet count()

Кеширование

Часто вычисление значения является дорогостоящим (т. Е. Ресурсоемким и медленным), поэтому может быть огромная выгода от сохранения значения в быстро доступном кэше, готовом к следующему требованию.

Это достаточно важная и мощная техника, поэтому Django включает в себя комплексную структуру кеширования, а также другие более мелкие функции кеширования.

Фреймворк кеширования

Фреймворк кэширования Django предлагает очень значительные возможности для повышения производительности за счет сохранения динамического содержимого, так что его не нужно рассчитывать для каждого запроса.

Для удобства Django предлагает разные уровни детализации кеширования: вы можете кэшировать вывод определенных представлений или только те части, которые сложно создать, или даже весь сайт.

Реализацию кэширования не следует рассматривать как альтернативу улучшению кода, который плохо работает из-за того, что он плохо написан. Это один из последних шагов на пути к созданию хорошо работающего кода, а не ярлык.

cached_property

Часто приходится вызывать метод экземпляра класса более одного раза. Если эта функция стоит дорого, то это может быть расточительным.

Использование cached_propertyдекоратора сохраняет значение, возвращаемое свойством; в следующий раз, когда функция будет вызвана в этом экземпляре, она вернет сохраненное значение, а не повторно вычислит его. Обратите внимание, что это работает только с методами, которые принимают в selfкачестве единственного аргумента, и что он изменяет метод на свойство.

Некоторые компоненты Django также имеют собственные функции кэширования; они обсуждаются ниже в разделах, относящихся к этим компонентам.

Понимание лени

Лень - это стратегия, дополняющая кеширование. Кэширование позволяет избежать повторных вычислений за счет сохранения результатов; лень откладывает вычисления до тех пор, пока они действительно не потребуются.

Лень позволяет нам ссылаться на вещи до того, как они будут созданы, или даже до того, как их можно будет создать. Это имеет множество применений.

Например, отложенный перевод можно использовать еще до того, как целевой язык станет известен, потому что он не выполняется до тех пор, пока фактически не потребуется переведенная строка, например, в визуализированном шаблоне.

Лень - это также способ сэкономить силы, в первую очередь пытаясь избежать работы. То есть один аспект лени заключается в том, что ничего не делать до тех пор, пока это не нужно делать, потому что в конце концов это может оказаться ненужным. Следовательно, лень может сказаться на производительности, и чем дороже соответствующая работа, тем больше пользы можно получить от лени.

Python предоставляет ряд инструментов для отложенного вычисления, в частности, с помощью конструкций генератора и выражения генератора . Стоит прочитать о ленивости в Python, чтобы открыть для себя возможности использования ленивых шаблонов в вашем коде.

Лень в Django

Сам Django довольно ленив. Хороший пример этого можно найти в оценке QuerySets. QuerySets ленивы . Таким образом, QuerySetможно создавать, передавать и комбинировать с другими QuerySets, фактически не совершая каких-либо обращений к базе данных для извлечения описываемых элементов. Передается QuerySetобъект, а не набор элементов, которые в конечном итоге потребуются от базы данных.

С другой стороны, некоторые операции заставят вычислить QuerySet . Избегая преждевременной оценки, вы QuerySetможете сэкономить на дорогостоящем и ненужном обращении к базе данных.

Django также предлагает keep_lazy()декоратор. Это позволяет функции, которая была вызвана с ленивым аргументом, вести себя лениво и оцениваться только тогда, когда это необходимо. Таким образом, ленивый аргумент - который может оказаться дорогостоящим - не будет использоваться для оценки, пока он не потребуется строго.

Базы данных

Оптимизация базы данных

Уровень базы данных Django предоставляет различные способы помочь разработчикам добиться максимальной производительности от своих баз данных. В документации по оптимизации базы данных собраны ссылки на соответствующую документацию и добавлены различные советы, описывающие шаги, которые необходимо предпринять при попытке оптимизировать использование базы данных.

Производительность HTTP

Промежуточное ПО

Django поставляется с несколькими полезными промежуточными программами, которые могут помочь оптимизировать производительность вашего сайта. Они включают:

ConditionalGetMiddleware

Поддержка Прибавляет для современных браузеров условно получать ответы , основанные на ETagи Last-Modifiedзаголовках. При необходимости он также вычисляет и устанавливает ETag.

GZipMiddleware

Сжимает ответы для всех современных браузеров, экономя трафик и время передачи. Обратите внимание, что GZipMiddleware в настоящее время считается угрозой безопасности и уязвим для атак, которые сводят на нет защиту, обеспечиваемую TLS / SSL. См. Предупреждение в разделе GZipMiddlewareдля получения дополнительной информации.

Сессии

Использование кешированных сессий

Использование кэшированных сеансов может быть способом повышения производительности за счет устранения необходимости загружать данные сеанса из более медленного источника хранения, такого как база данных, и вместо этого хранить часто используемые данные сеанса в памяти.

Статические файлы

Статические файлы, которые по определению не являются динамическими, являются отличной целью для оптимизации.

ManifestStaticFilesStorage

Воспользовавшись возможностями кэширования веб-браузеров, вы можете полностью исключить попадания в сеть для данного файла после начальной загрузки.

ManifestStaticFilesStorageдобавляет тег, зависящий от содержимого, к именам файлов статических файлов, чтобы браузеры могли безопасно кэшировать их в течение длительного времени без пропуска будущих изменений - при изменении файла тег изменится, поэтому браузеры автоматически перезагрузят ресурс.

«Минификация»

Некоторые сторонние инструменты и пакеты Django предоставляют возможность «минимизировать» HTML, CSS и JavaScript. Они удаляют ненужные пробелы, символы новой строки и комментарии, а также сокращают имена переменных и, таким образом, уменьшают размер документов, публикуемых вашим сайтом.

Производительность шаблона

Обратите внимание, что:

  • использование быстрее, чем использование{% block %}{% include %}
  • сильно фрагментированные шаблоны, собранные из множества мелких частей, могут повлиять на производительность

Кешированный загрузчик шаблонов

Включение часто значительно улучшает производительность, поскольку позволяет избежать компиляции каждого шаблона каждый раз, когда он должен быть отрисован.cached template loader

Использование разных версий доступного ПО

Иногда стоит проверить, доступны ли другие, более эффективные версии программного обеспечения, которое вы используете.

Эти методы нацелены на более продвинутых пользователей, которые хотят раздвинуть границы производительности уже хорошо оптимизированного сайта Django.

Однако они не являются волшебным решением проблем с производительностью, и вряд ли они принесут лучшую, чем минимальную прибыль, сайтам, которые еще не делают более простые вещи правильным образом.

Примечание

Стоит повторить: поиск альтернатив программному обеспечению, которое вы уже используете, никогда не является первым ответом на проблемы с производительностью . Когда вы достигнете этого уровня оптимизации, вам понадобится формальное решение для тестирования производительности.

Новее часто - но не всегда - лучше

Довольно редко новая версия хорошо обслуживаемого программного обеспечения оказывается менее эффективной, но специалисты по сопровождению не могут предвидеть все возможные варианты использования - поэтому, зная, что новые версии, вероятно, будут работать лучше, не предполагайте, что они всегда будут.

Это верно в отношении самого Django. Последовательные выпуски предлагали ряд улучшений во всей системе, но вы все равно должны проверять реальную производительность вашего приложения, потому что в некоторых случаях вы можете обнаружить, что изменения означают, что оно работает хуже, чем лучше.

Более новые версии Python, а также пакетов Python также часто будут работать лучше, но измерять, а не предполагать.

Примечание

Если вы не столкнулись с необычной проблемой производительности в конкретной версии, вы, как правило, найдете лучшие функции, надежность и безопасность в новом выпуске, и эти преимущества гораздо более значительны, чем любая производительность, которую вы можете выиграть или потерять.

Альтернативы языку шаблонов Django

Почти во всех случаях вполне подходит встроенный язык шаблонов Django. Однако, если кажется, что узкие места в вашем проекте Django кроются в системе шаблонов, и вы исчерпали другие возможности, чтобы исправить это, альтернативой может быть сторонняя альтернатива.

Jinja2 может предложить улучшения производительности, особенно когда дело доходит до скорости.

Альтернативные системы шаблонов различаются по степени общего использования языка шаблонов Django.

Примечание

Если у вас возникают проблемы с производительностью в шаблонах, первое, что нужно сделать, - это понять, почему именно. Использование альтернативной системы шаблонов может оказаться быстрее, но те же преимущества могут быть доступны и без особых проблем - например, дорогостоящая обработка и логика в ваших шаблонах могут быть выполнены более эффективно в ваших представлениях.

Альтернативные программные реализации

Возможно, стоит проверить, предоставлено ли программное обеспечение Python, которое вы используете, в другой реализации, которая может выполнять тот же код быстрее.

Однако большинство проблем с производительностью на хорошо написанных сайтах Django связано не с уровнем выполнения Python, а с неэффективными запросами к базе данных, кешированием и шаблонами. Если вы полагаетесь на плохо написанный код Python, ваши проблемы с производительностью вряд ли можно решить, если он будет выполняться быстрее.

Использование альтернативной реализации может вызвать проблемы совместимости, развертывания, переносимости или обслуживания. Само собой разумеется, что перед принятием нестандартной реализации вы должны убедиться, что она обеспечивает достаточный прирост производительности для вашего приложения, чтобы перевесить потенциальные риски.

Помня об этих предостережениях, вы должны знать:

PyPy

PyPy - это реализация Python на самом Python («стандартная» реализация Python находится на C). PyPy может предложить существенный прирост производительности, как правило, для тяжелых приложений.

Ключевой целью проекта PyPy является совместимость с существующими API и библиотеками Python. Django совместим, но вам нужно будет проверить совместимость других библиотек, на которые вы полагаетесь.

Реализации C библиотек Python

Некоторые библиотеки Python также реализованы на C и могут быть намного быстрее. Они стремятся предложить одинаковые API. Обратите внимание, что проблемы совместимости и различия в поведении известны (и не всегда очевидны).

Copyright ©2021 All rights reserved