Revisando el rendimiento de los marcos de Python para el desarrollo web

Recientemente tuve que comenzar un proyecto para un nuevo servicio web, y decidí probar la capacidad de carga máxima de Django y al mismo tiempo compararla con Flask y AIOHTTP. El resultado me pareció inesperado, así que lo dejaré aquí.



Los siguientes diagramas muestran los resultados del Apache Benchmark más simple para los frameworks Django versión 3.1, Flask 1.1 y AIOHTTP 3.7. AIOHTTP se ejecuta en modo asíncrono "normal" de un solo subproceso, Django y Flask son servidos por un servidor WSGI síncrono Gunicorn con el número de subprocesos igual al número de núcleos de procesador disponibles * 2. ASGI no participó en la prueba.



Condiciónes de la prueba
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 de ejecutar la prueba en una máquina local (4 núcleos de CPU):







UPD: como se escribe correctamente en los comentarios, para una comparación honesta, debe ejecutar AIOHTTP detrás de Gunicorn o reducir el número de trabajadores a 1.



La misma prueba en un VDS de un solo procesador real (el ping es aproximadamente 45 ms):







Durante la prueba, AIOHTTP usó el 100% de un núcleo de CPU, Flask y Django, el 100% de todos los núcleos disponibles.



conclusiones



De hecho, comparar aplicaciones asincrónicas y multiproceso no es del todo correcto: resuelven diferentes problemas. Por lo tanto, el resultado parece bastante lógico: en la prueba local, AIOHTTP simplemente tenía menos recursos, en igualdad de condiciones el rendimiento se nivela.



Pero el modesto resultado de Flask es difícil de explicar, no logré "overclockear" este marco.



All Articles