Бенчмарки¶
Что здесь измеряется
Только накладные расходы фреймворка: роутинг, разбор запроса, сборка
ответа. Бенчмарк вызывает ASGI-приложение каждого фреймворка напрямую, в
одном процессе — без сети и без веб-сервера. О сквозной HTTP-пропускной
способности он не говорит ничего: там у обоих фреймворков одинаково
доминируют uvicorn и база данных.
Как замерялось¶
- Два одинаковых endpoint'а в каждом фреймворке: статический
GET /v1/pingи динамическийGET /v1/item/{id}. - 1 000 вызовов на прогрев, затем 50 000 замеряемых. В таблице — медиана трёх прогонов.
- Логирование запросов выключено в обоих приложениях, чтобы в замер не попадал вывод в консоль.
- Перед замером проверено, что оба приложения возвращают одинаковые ответы 200.
Результаты¶
Python 3.14.3, Windows 11, AMD Ryzen, FastAPI 0.139. Абсолютные числа зависят от машины — важны соотношения.
| Маршрут | EndoCore | FastAPI | Соотношение |
|---|---|---|---|
Статика GET /v1/ping |
23 800 req/s (42 µs) | 11 000 req/s (91 µs) | 2.2× |
Динамика GET /v1/item/{id} |
30 800 req/s (32 µs) | 8 600 req/s (116 µs) | 3.6× |
Откуда разрыв¶
EndoCore резолвит маршрут одним проходом по trie, построенному при старте, а
обычный handler(request) вообще пропускает разрешение зависимостей. FastAPI
гоняет свою машинерию валидации и сериализации даже там, где она не нужна —
эта работа покупает фичи, но на тривиальном endpoint'е это чистые накладные
расходы. Голый Starlette оказался бы куда ближе к EndoCore.
Важен ли этот разрыв на практике? Редко. Диспатч стоит 30–120 µs; один индексированный запрос к базе стоит дороже. Выбирайте фреймворк по удобству, а не по этой таблице.
Воспроизвести¶
Скрипт (benchmarks/bench.py) собирает оба приложения, прогревает их и печатает req/s и соотношение для каждого маршрута.
Что не измеряется¶
- HTTP-транспорт — это
uvicorn, одинаковый у обоих. - Сериализация больших JSON — оба endpoint'а возвращают крошечные тела.
- Латентность базы — обычное настоящее узкое место; асинхронная ORM держит event loop свободным, пока идут запросы.