Python любят за простоту, но часто ругают за медлительность. Каждый год появляется новый бенчмарк, где Python оказывается в десятки или даже сотни раз медленнее C или Rust. Обычно после этого начинается спор: одни говорят, что «бенчмарки ничего не значат», другие — что «надо просто писать на нормальных языках».
Но реальность, как обычно, сложнее.
Один разработчик решил не спорить, а проверить: что именно происходит, если последовательно применять все известные способы ускорения Python. От простого обновления версии до JIT-компиляции, NumPy и даже Rust-модулей.
Получилась своеобразная «лестница оптимизации» — каждый следующий шаг даёт ускорение, но требует всё больше усилий.
И результат оказался неожиданным: Python можно ускорить до 1633 раз.
Но есть нюанс.
🧠 Почему Python медленный
Главная причина медлительности Python — не интерпретатор и даже не GIL, как принято думать.
Настоящая причина — гипердинамичность языка.
Python позволяет:
⚙️ менять методы классов прямо во время выполнения
⚙️ подменять встроенные функции
⚙️ менять наследование классов на лету
⚙️ переопределять операторы.
Это удобно для разработчиков, но кошмар для оптимизации.
Когда CPU видит в C выражение:
a + b
он просто выполняет одну инструкцию.
В Python всё гораздо сложнее.
Интерпретатор должен проверить:
🧩 какой тип у a
🧩 какой тип у b
🧩 не переопределён ли оператор +
🧩 не является ли объект подклассом с собственным __add__.
Каждая операция — это цепочка проверок.
🧱 Цена Python-объекта
Ещё одна причина — сами объекты Python.
В C число занимает:
📦 4 байта
А Python-число выглядит примерно так:
📦 ссылка на тип
📦 счётчик ссылок
📦 размер числа
📦 само значение.
В итоге:
📈 около 28 байт
То есть 4 байта данных и 24 байта служебной информации.
Когда таких объектов миллионы, разница становится огромной.
🪜 Лестница оптимизации Python
Исследователь протестировал разные способы ускорения Python на трёх задачах:
⚙️ физическая симуляция n-body
⚙️ математический тест spectral-norm
⚙️ реальный pipeline обработки JSON.
Каждый инструмент оказался новой ступенью лестницы.
🚀 Шаг 1 — просто обновить Python
Самый дешёвый способ ускорения.
CPython 3.11 получил большой апдейт проекта Faster CPython.
Он добавил:
⚙️ адаптивную специализацию байткода
⚙️ inline-кэширование
⚙️ ускоренную обработку исключений.
Результат:
📈 примерно 1.4× ускорение
И это буквально бесплатный апгрейд.
Если проект всё ещё работает на Python 3.9 или 3.10 — вы буквально теряете производительность.
⚡ Шаг 2 — альтернативные интерпретаторы
Следующая ступень — другой runtime.
Самые известные:
⚙️ PyPy
⚙️ GraalPy.
Они используют JIT-компиляцию, превращая горячие участки Python-кода в машинный код.
Результаты впечатляют:
📈 PyPy — до 13× быстрее
📈 GraalPy — до 66× быстрее.
Но есть проблемы.
⚠️ не все библиотеки работают
⚠️ C-расширения могут тормозить
⚠️ иногда долгий старт программы.
🧩 Шаг 3 — mypyc
Интересный инструмент — mypyc.
Он компилирует типизированный Python-код в C.
То есть обычные аннотации типов:
def advance(dt: float, n: int) -> None:
уже позволяют компилятору оптимизировать код.
Результаты:
📈 2× – 14× ускорение
Причём без изменения синтаксиса языка.
Фактически это превращает Python в статически типизированный язык на горячих участках.
🔬 Шаг 4 — NumPy
Если задача связана с математикой или матрицами, начинается магия.
NumPy выполняет вычисления не в Python, а в оптимизированных библиотеках:
⚙️ BLAS
⚙️ SIMD
⚙️ многопоточность.
Результат в тесте spectral-norm:
📈 520× ускорение
Да, именно так.
Python здесь работает просто как оркестратор для C-кода.
🧠 Шаг 5 — JAX и JIT-компиляция
Самый неожиданный результат показал JAX.
Это библиотека для научных вычислений, которая компилирует код через систему XLA JIT.
В тесте spectral-norm:
📈 1633× быстрее Python
То есть программа, которая работала 14 секунд, выполняется за 8.6 миллисекунды.
Причина проста.
JAX компилирует всю функцию целиком, не возвращаясь в Python между операциями.
⚙️ Шаг 6 — Numba
Numba — ещё один JIT-компилятор, но проще в использовании.
Достаточно добавить один декоратор:
@njit
И функция будет компилироваться через LLVM.
Результаты:
📈 56× – 135× ускорение
Но есть ограничения.
Numba любит:
⚙️ NumPy-массивы
⚙️ численные типы.
А вот строки и словари ему не нравятся.
🧱 Шаг 7 — Cython
Cython позволяет писать C-подобный код в синтаксисе Python.
Он компилируется в C-расширение.
Результаты:
📈 до 124× быстрее
Но тут начинается сложность.
Чтобы получить максимум скорости, нужно:
⚙️ понимать модель памяти C
⚙️ вручную указывать типы
⚙️ избегать скрытых медленных операций.
Без этого Cython может работать почти так же медленно, как Python.
🦀 Последняя ступень — Rust
На вершине лестницы находится Rust через PyO3.
Здесь горячие участки кода пишутся на Rust, а Python используется как оболочка.
Результат:
📈 113× – 154× ускорение
Но самое интересное — не в скорости.
Rust может вообще не создавать Python-объекты.
Например, он может:
⚙️ парсить JSON напрямую
⚙️ работать с нативными структурами
⚙️ передавать Python только готовый результат.
🧩 Реальность: потолок часто всего 4×
Самый честный результат исследования связан не с математикой, а с реальной задачей.
Pipeline обработки JSON-данных.
Когда данные уже представлены как Python-словарь:
📈 CPython → Cython = всего 4× ускорение
Почему?
Потому что главный тормоз Python — создание объектов.
Особенно:
⚠️ dict
⚠️ строки
⚠️ списки.
Именно поэтому настоящая оптимизация часто выглядит так:
👉 не ускорить цикл
👉 перестать создавать миллионы Python-объектов.
🧠 Мой главный вывод
Вся эта лестница отлично показывает одну важную мысль.
Python медленный не потому что язык плохой.
Он медленный потому, что:
🧠 создаёт много объектов
🧠 проверяет типы во время выполнения
🧠 остаётся максимально динамичным.
Но если вынести тяжёлые вычисления в:
⚙️ NumPy
⚙️ JAX
⚙️ Numba
⚙️ Cython
⚙️ Rust
— Python превращается в очень быстрый управляющий язык.
И это его настоящая роль.
🔮 Когда стоит оптимизировать
Есть простое правило, которое подтвердило это исследование.
🧠 сначала профилируй код
🧠 потом оптимизируй.
Часто оказывается, что:
⚙️ программа упирается в сеть
⚙️ или в базу данных
⚙️ или в чтение файлов.
В этих случаях оптимизация Python-циклов вообще ничего не даст.
Но если задача вычислительная — Python может стать быстрее в тысячу раз.
Главное — выбрать правильную ступень лестницы.
Источники
🔗 https://cemrehancavdar.com/2026/03/10/optimization-ladder/
🔗 https://telegra.ph/Lestnica-optimizacii-Kak-zastavit-Python-letat-i-stoit-li-ehto-usilij-03-14
🔗 https://github.com/cemrehancavdar/faster-python-bench