Revisitando o desempenho de estruturas Python para desenvolvimento web

Recentemente tive que iniciar um projeto para um novo serviço web, e decidi testar a capacidade máxima de carga do Django, e ao mesmo tempo compará-la com Flask e AIOHTTP. O resultado me pareceu inesperado, então vou deixá-lo aqui.



Os diagramas abaixo mostram os resultados do Apache Benchmark mais simples para os frameworks Django versão 3.1, Flask 1.1 e AIOHTTP 3.7. AIOHTTP roda em modo assíncrono "regular" de thread único, Django e Flask são servidos por um servidor WSGI síncrono Gunicorn com o número de threads igual ao número de núcleos de processador disponíveis * 2. ASGI não participou do teste.



Condições de teste
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», .



Resultados da execução do teste em uma máquina local (4 núcleos de CPU):







UPD: conforme eles escrevem corretamente nos comentários, para uma comparação honesta, você deve executar AIOHTTP atrás do Gunicorn ou reduzir o número de trabalhadores para 1.



O mesmo teste em um VDS de processador único real (ping é cerca de 45 ms):







Durante o teste, AIOHTTP usou 100% de um núcleo de CPU, Flask e Django - 100% de todos os núcleos disponíveis.



conclusões



Na verdade, comparar aplicativos assíncronos e multithread não é totalmente correto - eles resolvem problemas diferentes. Portanto, o resultado parece bastante lógico: no teste local, AIOHTTP simplesmente tinha menos recursos, em igualdade de condições o desempenho é nivelado.



Mas o modesto resultado do Flask é difícil de explicar, não consegui fazer um "overclock" neste framework.



All Articles