Самые быстрые Python веб-фреймворки в 2019

Автор оригинала: Maksim Larkin
  • Перевод


В 2018 году Python укрепил свои позиции популярности среди программистов и вошел в Top 3 самых популярных языков на github. Все больше и больше людей переходит на светлую сторону…то есть Python. Появилось еще большее количество разработчиков, которые интересуются данным языком и ведут разработку своих проектов с его помощью. Одним из популярных направлений для Python является web-разработка. Хочется, чтобы не только процесс разработки был удобным и быстрым, но и сами проекты могли похвастаться скоростью и стабильностью работы.

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

Поэтому мы решили составить сравнительный анализ популярных фреймворков, которые не потеряют, мы надеемся, своей актуальности на протяжении всего 2019 года и определить самый быстрый из них.

Участники тестирования


Django




Версия: 2.1.4
Описание: самый популярный комбайн для Python, который из коробки решает множество проблем (админка, авторизация, логирование, ORM, и т.д). Это упрощает жизнь разработчика, но если мы ставим в приоритет скорость работы — то иногда такой комбайн играет против нас и это сказывается на производительности. По этой причине номинацию Fastest Python Web Framework in 2019 он скорее всего не возьмет.

Flask




Версия: 1.0.2
Описание: самый популярный фреймворк на Python (по звездам в GitHub обгоняет даже Django). Популярный выбор в случаях разработки мелких проектов, для которых не нужны те плюшки, которые есть в Django. Позволяет быстро развернуть приложение. Возможно быстрее чем Django по скорости работы, но имеет очень маленькую функциональность “из коробки”.

AioHTTP




Версия: 3.5.1
Описание: очень привлекательный асинхронный Python Framework. Имеет версию клиента и сервера, что значительно развязывает руки при разработке. Обладает очень удобными асинхронными запросами с версии клиента, а также очень хорошие показатели скорости работы сервера при большом количество запросов. Точно должен попасть в тройку лидеров.

Sanic




Версия: 18.12
Описание: можно сказать, что это “многопоточный Flask” со всеми вытекающими. По этой причине мы думаем, что результаты должны быть очень хороши.

Tornado




Версия: 5.1.1
Описание: асинхронный ветеран Python движения, задавший тренд асинхронности в 2010 году. Не теряет своей актуальности и получил 5ю версию в 2018 году. Достаточно высокий порог входа для новичков. Популярен среди олдскульных питонистов, и мы думаем не зря. Должен показать хорошие результаты.

Vibora




Тестируемая версия: релизов на GitHub нет
Описание: многообещающий фреймворк, появившийся в июне 2018 и за последнии полгода набравший более 4000 звезд. Имеет впечатляющие замеры производительности в GitHub. Мы думали именно Vibora станет фаворитом нашей гонки, но к сожалению из-за отсутствия возможности запуска под Python >=3.7 и отсутствия стабильной версии фреймворка мы исключили Vibora.
В GitHub разработчики обещают “кардинально новый” Vibora уже скоро. Посмотрим, что у них получится и обязательно напишем об этом.

Методика тестирования


Тестирование проводилось на Apple iMac 27'' Retina 5K 2017, CPU: 3.5GHz i5, RAM: 8GB, 1000GB Fusion Drive, OSX 10.14.2 при помощи утилиты WRK:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/db/

Тесты проводились на Python 3.7.2. Все фреймворки запускались при помощи Gunicorn с двумя воркерами. Возможно в каких-то случаях использование uwsgi сказалось бы на результатах, но так как мы поставили цель тестировать фреймворки, а не способы их запуска — решили этим пренебречь.

У нас был всего один вид тестов: DB Test, в котором мы получаем строковые данные из базы данных и возвращаем их в виде html-ответа (1 запись в 79 bytes). В качестве базы данных использовался Postgres 11. В качестве драйвера обращений к базе использовался psycopg2 в случае синхронных фреймворков и asyncpg в случае асинхронных.

В качестве event loop библиотеки для асинхронных фреймворков решили использовать uvloop.

Результаты


Запросов в секунду



Вполне ожидаемые лидирующие позиции aiohttp и Sanic, но неожиданные результаты от Tornado.

Передача данных в секунду (Кб)



По количеству переданных данных в секунду Django сильно отстает.

Среднее время запроса (мс)



Снова неприятно удивляет Tornado, на который мы изначально делали ставку. Впечатляет Flask, который по среднему времени запроса конкурирует с потенциальными лидерами.

Максимальное время запроса (сек)



Все “подопытные” показали практически одинаковые результаты по максимальному времени запроса. Все, как мы и ожидали.

Финальные результаты


12 threads


400 connections


Avg Max Requests/sec Transfer/sec (KB)
Latency (ms) Req/Sec Latency (ms) Req/Sec
Django 147,99 120,91 1,98 640 425,71 78,99
Flask 186,8 65,65 1,75 280 546,2 127,48
aiohttp 165,07 247,16 1,98 585 1966,28 439,72
Sanic 194,8 170,85 1,98 470 1520,9 292,6
Tornado 279,3 101,71 1,74 272 778,75 222,07

Итоги


Aiohttp: лидер по производительности на начало 2019 года. Если ваша задача требует ультимативной производительности — то стоит к нему присмотреться. К тому же можно поэкспериментировать с параметрами запуска aiohttp, чтобы выжать из него еще больше. Имеет версию клиента, что позволяет без дополнительных библиотек делать асинхронные запросы. Поэтому для реализации своего нового высоконагруженного сервиса мы выбрали его.

Sanic: популярность фреймворка идет впереди его производительности. Чуда не случилось и обогнать лидера не вышло. В совокупности с тредом на Reddit о проблемах c безопасностью — мы бы не стали использовать Sanic прямо сейчас и подождали действий от разработчиков.

Tornado: “разочарование года”. В связи с результатами — не думаем, что Tornado стоит выбирать для реализации каких-либо новых проектов. Надеемся разработчики что-нибудь придумают и исправят ситуацию.

Django показал ожидаемый результат. Мы любим Django за его возможности и избавление нас от рутины, а не за скорость работы. Обширное community, большое количество материалов в Сети, большое количество реализованных проектов в открытом доступе — все это делает его привлекательным для новичков. Если бы у нас стояла задача быстро разработать MVP типичного web-сервиса — мы бы выбрали в 2019 именно его.

Flask тоже показал ожидаемый результат. Обошел Django за счет того, что имеет не такой богатый функционал из коробки. Не дотянул до скорости асинхронных фреймворков. Мы бы выбрали его в 2019 для реализации небольших pet-проектов или тогда, когда уже важна скорость, но разбираться с асинхронными фреймворками желания еще нет.

Все исходные файлы бенчмарков вы можете посмотреть в репозитории Python Frameworks Benchmark.
Поделиться публикацией

Похожие публикации

Комментарии 29

    0

    А как же Starlette?

      0
      Я думаю это лучше уточнить у ребят, которые делали бенчмарк.

      Но если интересно мое мнение: то судя по статье они старались тестировать стабильные версии фреймворков, а Starlette еще не релизная. Но могу ошибаться
        0
        Спасибо за ссылку. Жаль пока нет поддержки HTTP2.
          0
          Какие он даст приемущества фреймворку?
            0
            В смысле фреймворку? Это дает преимущество людям которые его используют.
              0
              А не смогут люди воспользовать преимуществами http2 поставив проксирующий веб сервер? Оно и в плане горизонтального масштабирования получше.
        +1

        Не нужно было использовать Gunicorn: в документации того же aiohttp написано, что с Gunicorn он работает медленнее.


        По бенчмаркам без Gunicorn из первых ссылок в гугле Sanic выходит раза в полтора быстрее чем aiohttp

          +1
          Кстати, судя по гитхабу, оно всё ещё и в Docker запускается. Я не специалист, но много начитался про тормознутую сеть в докере и осмелюсь предположить, что это тоже может значительно влиять на результаты
            0
            В общем, попробовал сам запустить aiohttp и sanic без gunicorn. У aiohttp ничего принципиально не изменилось, а вот sanic стал в полтора раза быстрее и в итоге в 1.3 раза быстрее чем aiohttp
            +1
            Нет теста компилируемого фреймворка Falcon — статья бессмысленна.
            Согласно их тестам и Django и Flask уделываются в десятки раз, а значит и ваш фаворит скорее всего прогнётся.
              0

              Что значит "компилируемого"? Там просто все файлы транслируются в C-экстеншены с помощью cython. "Ситонизация" обычного питоновского кода почти не прибавляет к производительности такого кода. А чисто ситоновского оптимизированного кода там нет. Поэтому они и пишут, что:


                      print('\nNOTE: Cython not installed. '
                            'Falcon will still work fine, but may run '
                            'a bit slower.\n')

              "a bit slower"

                0
                А по тестам Falcon команды прирост производительности в 1.5 раза.
                  0

                  Это и есть "a bit faster" :)
                  Если бы они переписали код на чистом cython (pyx/pxd), производительность могла бы увеличиться в десятки раз (это, строго говоря, верно для какого-то вычислительного кода на питоне, потому как в случае web-фреймворка всё конечно сложнее). Но именно ситонизация py-кода даёт очень незначительный прирост так как выполняется тупая трансляция в CPython API со всем динамизмом, тогда как код на cython уже статически строго типизирован.

                    0
                    Вы можете называть это хоть a little bit faster, это всего-лишь слова. А в реальности на выходе мы имеет веб-приложение обрабатывающее в 1.5 раза больше запросов и это офигенно.
              +4

              Но ведь aiohttp не фреймворк для разработки сайтов (в отличии от Django). Мне сравнение больше напоминает подводную лодку против карьерного самосвала. Сравнить можно, но имеет ли оно смысл?

                0

                Великолепно разрабатываю на Tornado сайты. Вместе с Mako выходит очень удобно.
                Ну а если вспомнить что сейчас все чаще нужен json то вообще сказка. (для API)
                И в этом случае 1000 коннектов которые ждут ответа от БД или другого сервиса не убьют ваш сервер.

                +1
                По моему тут опять сравнили мягкое с пушистым. Как можно сравнивать скорость работы по числу запросов в секунду, если сравнивается всего ДВА воркера для синхронных фреймворков с условно бесконечным числом «воркеров» для асинхронных?
                В таком тесте корректнее сравнивать время на обработку одного запроса. По этому показателю в этом тесте победил Django.
                А если хочется сравнить число запросов в секунду, то надо значительно увеличить число воркеров для синхронных фреймворков. И заодно собрать статистику как от числа воркеров зависит число запросов в секунду и объём потребляемой памяти.
                  +1
                  условно бесконечным числом «воркеров» для асинхронных?

                  Вы же понимаете, что, если скажем, запрос в бд будет выполнятся очень быстро, то синхронные окажутся быстрее, потому что в асинке есть, например, оверхед на переключения.

                  0
                  Торнадо разочаровал.
                    0
                    Docker
                    OSX
                    Так стоп, я правильно понимаю, что это всё ещё и в VirtualBox запускалось?
                      0
                      Почитал матчасть — ну или HyperKit, что, впрочем, не лучше
                      +1
                      Bottle кто-то использует в наше время?
                        0
                        Bottle это по сути аналог Flask, и если ты хорошо знаешь питон и придерживаешься его дзена то используешь бутылку, если нет, то Flask.
                          0
                          А есть ли какие-то преимущества у Flask по сравнению с Bottle?
                        0
                        Quart тоже хорош? вроде его разработчик хвалился что он быстр!
                          0

                          Увидев результаты Торнадо я сразу понял что тут что то неладное и полез в код.
                          Короче вы какуето херню потестили.


                          1. Вы не использовали asyncpg для Торнадо а использовали старую momoko которая работает поверх psycopg.
                          2. НО самое главное вы не использовали uvloop вообще! Да даже больше вы не использовали async/await в Торнадо! Вы знаете что собственная реализация ioloop на базе yield и gen.coroutine является депрекейтед!? Вы должны были использовать async/await и asyncpg. В 6 Торнадо вообще не будет старого лупа только тот что в asyncio.
                            0
                            вы

                            Это перевод, если что. Предлагаю повторить всё это на английском в issues на гитхабе

                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              Сейчас произвел аналогичный тест (исходники из этой статьи, но без базы), обнаружил что у саника логи не выключены, ну и результаты соответственно:

                              aiohttp: 5681 rps
                              aiohttp + uvloop: 7780 rps
                              sanic (default): 6362 rps
                              sanic (logs off): 20956 rps

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое