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

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

Введение

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

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

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

С какой целью оптимизировать?

Важно четко понимать, что для вас значит «производительность». Нет единственного способа его измерить.

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

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

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

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

Анализ производительности («сравнительный анализ»)

Нет смысла просто гадать или делать предположения о слабых местах вашего кода.

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

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

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

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

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

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

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

Хорошее начало с самого начала

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

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

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

Django предлагает много разных подходов к вещам, но то, что можно сделать что-то определенным образом, не обязательно означает, что это самый правильный способ сделать это. Например, вы можете видеть, что одно и то же количество, количество элементов в коллекции, можно вычислить на уровне запроса 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 }}

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

Заметка

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

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

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

Кеширование

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

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

Инфраструктура кеширования

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

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

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

cached_property

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

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

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

Понимание задержки

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

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

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

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

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

Задержка в Django

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

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

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

Базы данных

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

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

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

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

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

ConditionalGetMiddleware

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

GZipMiddleware

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

Сессии

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

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

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

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

ManifestStaticFilesStorage

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

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

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

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

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

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

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

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

Включение часто значительно повышает производительность, поскольку устраняет необходимость компилировать каждый шаблон во время каждого рендеринга.chargeur de gabarits en cache

Использование разных доступных версий программного обеспечения

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

Эти методы предназначены для более продвинутых пользователей, которые хотят расширить пределы производительности уже хорошо оптимизированного сайта 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 ©2020 All rights reserved