В 2024 году Python занял первое место в рейтинге Tiobe. Он простой, универсальный, но медленнее других языков программирования. Как ускорить код на Python при помощи компилятора Numba, разбираемся в статье вместе с ведущим разработчиком 1С Владимиром Щеловым.
Плюсы и минусы Python
Python — это высокоуровневый язык программирования, один из самых популярных в мире. У него простой интуитивно понятный синтаксис, много готовых библиотек и фреймворков.
Обычно Python используют:
- для создания веб-сайтов и приложений;
- машинного обучения;
- написания скриптов при автоматизации рутинных задач;
- разработки простых игр;
- сбора, обработки и визуализации данных.

Однако у Python есть и недостатки, например скорость. По сравнению с Java или C это медленный язык программирования, потому что:
- программа не компилируется в машинный код заранее, а выполняется последовательно строка за строкой;
- Python использует динамическую типизацию: он сам определяет, какой тип данных хранится в переменной. Это требует дополнительных ресурсов в процессе выполнения;
- Python использует автоматическое управление памятью: не нужно вручную выделять и освобождать память, как в C или C++. Поэтому если программа работает с большим количеством данных или объектов, то может страдать производительность, поскольку управление памятью в этом случае может быть неоптимальным.
Как ускорить Python
Для ускорения кода Python чаще всего используют:
- Cython — это специальное расширение Python. С его помощью можно писать код, который выглядит как питон, но при этом включает в себя типизацию и другие конструкции, похожие на C. Cython компилирует код в C, таким образом повышая производительность программы.
- PyPy — альтернативная реализация языка Python, которая использует метод JIT. PyPy компилирует код в реальном времени, поэтому работает быстрее, чем стандартная реализация Python.
- Numba — еще один компилятор с открытым исходным кодом, переводит код на Python в машинный на лету.
Выбор между Cython, PyPy и Numba зависит от проекта и задачи. Например, Cython часто используют для оптимизации библиотек или интеграции с C. PyPy подходит, когда нужно ускорить весь проект, а Numba — для числовых вычислений и обработки массивов.
Как работает Numba
Numba помогает ускорить числовые вычисления. Она делает это с помощью компиляции — превращает код на питоне в машинные команды в режиме реального времени.
Нумба хорошо работает с библиотекой NumPy и не требует менять много кода. Чтобы ускориться, нужно просто добавить декоратор @jit перед функцией, которую нужно ускорить. В первый раз этот процесс может занять немного времени, но потом программа будет выполняться быстрее благодаря кэшированию.

Что можно разогнать
В функциях, скомпилированных с помощью Numba, можно использовать лишь ограниченный набор возможностей Python и Numpy. Есть операторы, функции и классы, которые она понимает, а есть — которые нет.
Например, Numba поддерживает:
- питоновские списки, которые позволяют быстро добавлять элементы в конец (при этом они должны состоять из элементов одного типа);
- NumPy-массивы, которых нет в стандартной библиотеке Python;
- кортежи (tuples), которые могут содержать элементы разных типов;
- типизированные словари из numba.typed с ключами и значениями одного типа (хотя они работают немного медленнее стандартных питоновских словарей);
- строки (str) и байты (bytes).
При этом Numba не поддерживает:
- питоновские словари (dict);
- списки с разнородными элементами;
- библиотеки SciPy и Pandas;
- множества (set);
- пользовательские классы и объекты Python;
- функции с динамической типизацией, например принимающие аргументы разных типов;
- генераторы и итераторы Python;
- стандартные функции Python, которые не имеют реализации в Numba, особенно те, которые требуют сложной логики или работы с объектами;
- асинхронные функции (async/await).
Как использовать Numba
Чтобы ускорить код на Python:
- Установите Numba через pip install numba или conda install numba.
- Импортируйте библиотеку в свой код.
from numba import jit
3. Добавьте декоратор @jit, чтобы ускорить функцию.
@jit def my_function(x): return x * 2
4. Сделайте вызов функции. Первый запуск займет некоторое время, но потом нумба сохранит скомпилированный код и функция будет выполняться быстрее.
Сейчас вместо @jit также используют декоратор @njit. При использовании @jit Numba на большой скорости доходит до неподдерживаемых операций, а затем замедляется до обычной скорости Python и сохраняет ее до конца функции. А @njit просто помечает их в качестве исключений. Поэтому этот вариант лучше подходит для достижения максимальной скорости.

Векторизация
Векторизация позволяет нумбе выполнять операцию над несколькими данными одновременно. А еще обрабатывать не один элемент данных за раз, а целые блоки. За счет избавления от явных циклов можно значительно ускорить процесс вычисления.
В результате код получается более компактным и понятным. Например, вместо цикла for для сложения двух массивов можно использовать просто операцию сложения между ними.
import numpy as np from numba import jit @jit def add_arrays(a, b): return a + b a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) result = add_arrays(a, b) print(result) # Вывод: [5 7 9]
Главное про ускорение Python с помощью Numba
- Python — это интерпретируемый язык программирования, у него легкий синтаксис, но низкая производительность.
- Для ускорения кода Python чаще всего используют расширения и JIT-компиляторы, которые переводят код в машинный вид на лету.
- Numba — это JIT-компилятор. Для запуска используют декоратор @jit или @njit для достижения максимальной скорости.
- Numba поддерживает ограниченный набор возможностей Python и Numpy.
- Векторизация позволяет обрабатывать не один элемент данных за раз, а целые блоки, что ускоряет процесс вычисления.