Revisiter les performances des frameworks Python pour le développement Web

Récemment, j'ai dû démarrer un projet pour un nouveau service Web, et j'ai décidé de tester la capacité de charge maximale de Django, et en même temps de la comparer avec Flask et AIOHTTP. Le résultat m'a semblé inattendu, alors je vais "juste le laisser" ici.



Les diagrammes ci-dessous montrent les résultats du Benchmark Apache le plus simple pour les frameworks Django version 3.1, Flask 1.1 et AIOHTTP 3.7. AIOHTTP fonctionne en mode asynchrone mono-thread "normal", Django et Flask sont servis par un serveur WSGI synchrone Gunicorn avec le nombre de threads égal au nombre de cœurs de processeur disponibles * 2. ASGI n'a pas participé au test.



Conditions d'essai
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», .



Résultats de l'exécution du test sur une machine locale (4 cœurs CPU):







UPD: comme ils l'écrivent à juste titre dans les commentaires, pour une comparaison honnête, vous devez soit exécuter AIOHTTP derrière Gunicorn, soit réduire le nombre de workers à 1.



Le même test sur un vrai VDS mono-processeur (le ping est d'environ 45 ms):







Pendant le test, AIOHTTP a utilisé 100% d'un cœur de processeur, Flask et Django - 100% de tous les cœurs disponibles.



conclusions



En fait, comparer des applications asynchrones et multithread n'est pas tout à fait correct - elles résolvent différents problèmes. Par conséquent, le résultat semble assez logique: dans le test local, AIOHTTP avait tout simplement moins de ressources, dans des conditions égales, les performances sont nivelées.



Mais le modeste résultat de Flask est difficile à expliquer, je n'ai pas pu "overclocker" ce cadre.



All Articles