В поисках Лучших Практик. Как грамотно ускорить и измерить Django?

Пишу я страничу для вывода отчетности, пишу, пишу, потом решаю загрузить в базу реальные данные и вижу в Django Toolbar 2 секунды на генерацию страницы, 150 запросов к базе данных за 200мс. А я бы не хотел, чтобы мои страницы отдавались быстрее 100мс.

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

P.S. отчасти на вопрос меня натолкнул рефакторинг, который заставил добавить огромное количество get_model вместо стандартного питоновского импорта дабы избежать кросс-импорта. Допустим, я не знаю, как это все работает. Что бы дало мне ответ, кушает ли такое решение ресурсы, или не кушает? А если кушает то могу много ли и нужно ли этого избегать? Что бы натолкнуло меня или моих коллег на инсайты по адекватной оптимизации?
  • Вопрос задан
  • 1200 просмотров
Решения вопроса 1
@IvanOne
Возможно не совсем ориентируюсь в данной теме, но понадобится профилировщик, https://github.com/rkern/line_profiler
habrahabr.ru/sandbox/54557
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
un1t
@un1t
Во первых не надо ничего кешировать и оптимизировать пока не выяснишь, что тормозит.

В дебуг тулбаре смотри нет ли из этих 150 кучи одинаковых запросов. Большая вероятность, что с помощью select_related и prefetch_related можно сократить количество запросов многократно.

Самый примитивный способ с помощью функции time() змерить сколько выполняются те или иные участки.

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

from decorator import decorator
from line_profiler import LineProfiler

@decorator
def profile_each_line(func, *args, **kwargs):
    profiler = LineProfiler()
    profiled_func = profiler(func)
    try:
        return profiled_func(*args, **kwargs)
    finally:
        profiler.print_stats()
Ответ написан
@zeroplay
Как делать это без боли, без втыкания профилирующих строчек в код, без знания структуры фреймворка на уровне контрибьютера?
без втыкания врят ли получится, даже из написанного выше понятно, что некоторая доля погружения обязательна (time - самое примитивное и надежное средство)
хотя некоторые считают, что таймлайна браузера вполне достаточно для выяснения узких мест))
Ответ написан
Комментировать
@bash77
неизвестно про что думать (входных данных нет)... ну можно:
попробуйте сменить движок шаблонов на jinja2.
затолкайте сессии в redis.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы