Как стать автором
Обновить

Ещё раз о производительности фреймворков Python для веб разработки

Время на прочтение2 мин
Количество просмотров12K
Недавно мне пришлось начинать проект нового веб сервиса, и я решил протестировать максимальную нагрузочную способность Django, а заодно сравнить её с Flask’ом и AIOHTTP. Результат показался мне неожиданным, поэтому я «просто оставлю» его тут.

На диаграммах ниже приведены результаты простейшего Apache Benchmark’a для фреймворков Django версии 3.1, Flask 1.1 и AIOHTTP 3.7. AIOHTTP работает в «штатном» однопоточном асинхронном режиме, Django и Flask обслуживаются синхронным WSGI сервером Gunicorn с числом потоков, равным числу доступных ядер процессора * 2. ASGI в тесте не участвовал.

Условия тестирования
Во всех трёх случаях выводится простая страница со списком по результатам выборки из реляционной базы данных PostgreSQL. Запрос я постарался сделать максимально приближенным к реальности:

SELECT r.id, r.auth_user_id, r.status, r.updated, r.label, r.content, u.username,
    ARRAY_AGG(t.tag) tag, COUNT(*) OVER() cnt,
    (
        SELECT COUNT(*) FROM record r2
            WHERE
                r2.parent_id IS NOT NULL
                AND r2.parent_id = r.id
                AND r2.status = 'new'
    ) AS parts
FROM record r
JOIN auth_user u ON u.id = r.auth_user_id
LEFT JOIN tag t ON t.kind_id = r.id AND t.kind = 'rec'
WHERE r.parent_id IS NULL AND r.status = 'new'
GROUP BY r.id, u.username
ORDER BY r.updated DESC
LIMIT 10 OFFSET 0

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

AIOHTTP использует пулл соединений с БД и драйвер asyncpg, Django и Flask — SQLAlchemy без ORM (для чистоты эксперимента) и psycopg2.

Приложение Django создано стандартными средствами фреймворка (django-admin startproject, manage.py startapp и т. д.), вывод тестовой страницы через ListView. Установки Flask и AIOHTTP построены на канонических веб приложениях «Hello, world», взятых из документации.

Результаты запуска теста на локальной машине (4 ядра CPU):



UPD: как справедливо пишут в комментариях, для честного сравнения следовало либо запустить AIOHTTP за Gunicorn'ом, либо уменьшить число воркеров до 1.

Тот же тест на реальном однопроцессорном VDS (пинг около 45 ms):



Во время теста AIOHTTP использовал 100% одного ядра CPU, Flask и Django — 100% всех доступных ядер.

Выводы


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

А вот скромный результат Flask’а с трудом поддается объяснению, «разогнать» этот фреймворк у меня не получилось.
Теги:
Хабы:
Всего голосов 14: ↑8 и ↓6+6
Комментарии15

Публикации

Истории

Работа

Python разработчик
127 вакансий
Data Scientist
72 вакансии

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
20 – 22 сентября
BCI Hack Moscow
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн