Python web-фреймворкиДанное тестирование содержит данные о работе python-фреймворков и сравнение «цены асинхронности» с синхронным WSGI-решениями. Участники тестирования (описания взяты с сайтов) - Aiohttp 0.16.3 - асинхронный фреймворк базирующийся на Asyncio;
- Bottle 0.12.8 - быстрый, простой и легковесный WSGI микрофреймвок;
- Django 1.8.2 - веб-фреймворк для перфекционистов с горящими сроками;
- Falcon 0.3.0 - высоко-производительный фреймворк для построения облачных API;
- Flask 0.10.1 - микрофреймворк основаный на Werkzeug, Jinja2 и хороших намерениях;
- Muffin 0.0.88 - асинхронный фреймворк на основе Asyncio и Aiohttp;
- Pyramid 1.5.7 - небольшой, быстрый и понятный веб-фреймворк;
- Tornado 4.2 - асинхронная сетевая библиотека и веб-фреймворк;
Методика тестирования Тесты проводились на Amazon EC2 t2.medium сервере. Для создания нагрузки использовалась утилита WRK запущенная на том же сервере с параметрами: wrk -d30s -t12 -c400 Все приложения (кроме Tornado) запускались при помощи Gunicorn (2 процесса на каждое). Для синхронных WSGI библиотек использовался Meinheld worker. Приложение на Tornado запускало 2 процесса, используя средства самого фреймворка. Все тесты производились с использованием Python 2.7.6. Каждое приложение тестировалось по трем основным сценариям: - JSON-тест - закодировать небольшой объект в JSON и вернуть клиенту.
- Remote-тест - загрузить ответ от другого сервера и вернуть его клиенту.
- Complete-тест - с помощью ORM загрузить коллекцию объектов из базы, добавить к ней еще один и отрендерить список в шаблоне.
Первый сценарий это простейший «Hello World!» немного усложненный кодированием в JSON и показывает скорость обработки HTTP-запросов. Второй сценарий показывает насколько хорошо фреймворк справляется с длительными операциями ожидания во время обработки запроса. Третий сценарий - комплексный тест и имитирует реальную жизнь, а именно использование базы данных, ORM, работу шаблонизатора. В качестве базы данных использовался Postgresql с дефолтными настройками. Исходники приложений - на Github. Результаты
Name | 50% (ms) | 75% (ms) | Avg (ms) | Req/s | Falcon | 19.24 | 19.81 | 19.19 | 20677.13 | Bottle | 24.77 | 26.23 | 25.06 | 15761.45 | Pyramid | 41.75 | 43.49 | 41.63 | 9402.69 | Flask | 64.32 | 71.59 | 65.68 | 6023.4 | Aiohttp | 91.67 | 103.1 | 108.01 | 4093.41 | Django | 103.2 | 112.19 | 103.36 | 3696.9 | Muffin | 108.07 | 115.09 | 171.56 | 3575.36 | Tornado | 138.24 | 149.84 | 136.87 | 2829.72 | В первом простом тесте на первых местах синхронные фреймворки. Асинхронные фреймворки в аутсайдерах. Name | 50% (ms) | 75% (ms) | Avg (ms) | Req/s | Timeouts | Aiohttp | 358.08 | 369.08 | 338.94 | 1120.27 | | Muffin | 372.95 | 428.75 | 376.98 | 1019.76 | | Tornado | 1994.39 | 2069.25 | 1928.31 | 194.37 | | Pyramid | 3295.1 | 10518.92 | 6673.78 | 19.35 | 338 | Falcon | 3196.23 | 12976.84 | 6696.17 | 19.28 | 328 | Flask | 3306.88 | 11690.8 | 6824.88 | 19.16 | 363 | Bottle | 3363.74 | 9911.84 | 6403.92 | 19.09 | 335 | Django | 3317.64 | 12954.23 | 6918.64 | 18.96 | 300 | Для понимания результатов этого теста необходимо пояснить, что приложения обращались к nginx настроенному на ответ с задержкой 100ms. Из-за этого результаты синхронных фреймворков очень близки. Name | 50% (ms) | 75% (ms) | Avg (ms) | Req/s | Timeouts | Aiohttp | 151.78 | 156.9 | 254.75 | 1004.82 | 236
| Muffin | 420.14 | 485.4 | 1552.7 | 819.62 | | Bottle | 613.5 | 630.17 | 1062.86 | 451.34 | 178 | Tornado | 937.37 | 988.86 | 910.06 | 418.36 | | Falcon | 766.75 | 805.35 | 1457.99 | 350.26 | 81 | Pyramid | 562.44 | 601.49 | 812.43 | 248.42 | 235 | Flask | 1032.63 | 1649.89 | 1465.25 | 222.78 | 496 | Django | 1610.46 | 1976.44 | 2632.36 | 88.57 | 42 |
|