The future of Python web services looks GIL-free
Python 3.14 представляет значительный прорыв для многопоточного Python, так как его "free-threaded" вариант достиг фазы II и больше не считается экспериментальным. Производительность улучшилась с 35% штрафом до всего 5-10%, а реализация теперь использует адаптивный интерпретатор без обходных решений из Python 3.13. Автор, разработчик веб-фреймворка и веб-сервера, провел сравнительное тестирование для веб-приложений, так как большинство существующих сервисов являются I/O-bound, а многопоточность критически важна.
Для тестирования были созданы ASGI-приложение на FastAPI и WSGI-приложение на Flask, каждый с двумя конечными точками: генератором JSON и имитацией I/O-операции с задержкой 10мс. Использовался сервер Granian, который работает с потоками вместо процессов, и инструмент rewrk для нагрузки. Цель - определить, можно ли наконец отказаться от гигабайтов памяти, тратимых на multiprocessing для параллельной обработки запросов в веб-сервисах.
Комментарии (78)
- Появление free-threading в 3.13-3.14 сделало C-расширения, не обновлённые под free-threading, небезопасными и требует их обновления.
- Сообщество обсуждает, что отсутствие GIL в 3.14 может привести к тому, что старые библиотеки будут вести себя непредсказуемо, и предлагает, чтобы CPython поставлял инструмент для сканирования и обновления кода.
- Участники обсуждают, что влияние free-threading на производительность варьируется от «ничего не изменилось» до «значительно лучше» в зависимости от IO vs CPU bound кода, и что влияние на реальные приложения будет варьироваться от «ничего» до «значительно лучше».
Python has had async for 10 years – why isn't it more popular? 🔥 Горячее 💬 Длинная дискуссия
- Async в Python уже 10 лет, но до сих пор не стал мейнстримом.
- Причины:
- ошибки «забыл
await», трудно отлаживать; - GIL приучил не думать о параллелизме;
- польза только при I/O-задачах, CPU-нагрузка не ускоряется;
- фреймворки не догнали: Django ORM всё ещё синхронен, Flask тоже.
- ошибки «забыл
- Классический кейс — HTTP-запросы: стартуем сотни корутин, ждём ответов, не блокируем интерпретатор.
- Но дисковый I/O, CPU-задачи и другие сценарии не так выигрывают.
- Вывод: чтобы новые фичи 3.14 (free-threading, sub-interpreters) не повторили судьбу async, нужно:
- чётко объяснять, какие задачи они решают;
- давать простые API и инструменты отладки;
- не ждать, пока экосистема «догонит», а сразу внедрять в популярные библиотеки.
Комментарии (234)
- Async в Python пришёл «слишком поздно»: к моменту появления asyncio большинство уже решали задачи I/O через forking, multiprocessing или сторонние библиотеки.
- «Цветные функции» и необходимость переписывать весь код ради async делают его «заразным» и несовместимым с существующими синхронными библиотеками.
- Сложная семантика (event-loop, await, cancellation-исключения), плохая документация и отсутствие понятных best-practice усложняют отладку и поддержку.
- Для большинства задач Python-разработчика async не критичен: WSGI/WSGI-совместимые решения, Celery, Kafka и простое горизонтальное масштабирование покрывают потребности.
- Альтернативы (trio, anyio, gevent) и другие языки (Go, Elixir) предлагают более простые модели конкурентности без «раскрашенных» функций.