Баннер мобильный (3) Пройти тест

Что такое Numba и как ускорить код на Python

Сохранить достоинства и компенсировать недостатки популярного языка

Разбор

13 марта 2025

Поделиться

Скопировано
Что такое Numba и как ускорить код на Python

Содержание

    В 2024 году Python занял первое место в рейтинге Tiobe. Он простой, универсальный, но медленнее других языков программирования. Как ускорить код на Python при помощи компилятора Numba, разбираемся в статье вместе с ведущим разработчиком 1С Владимиром Щеловым.

    Плюсы и минусы Python

    Python — это высокоуровневый язык программирования, один из самых популярных в мире. У него простой интуитивно понятный синтаксис, много готовых библиотек и фреймворков

    Обычно Python используют: 

    • для создания веб-сайтов и приложений;
    • машинного обучения;
    • написания скриптов при автоматизации рутинных задач;
    • разработки простых игр;
    • сбора, обработки и визуализации данных.
    Python
    Код на Python. Источник

    Однако у Python есть и недостатки, например скорость. По сравнению с Java или C это медленный язык программирования, потому что: 

    • программа не компилируется в машинный код заранее, а выполняется последовательно строка за строкой;
    • Python использует динамическую типизацию: он сам определяет, какой тип данных хранится в переменной. Это требует дополнительных ресурсов в процессе выполнения;
    • Python использует автоматическое управление памятью: не нужно вручную выделять и освобождать память, как в C или C++. Поэтому если программа работает с большим количеством данных или объектов, то может страдать производительность, поскольку управление памятью в этом случае может быть неоптимальным.

    Python — это интерпретируемый язык программирования с легким синтаксисом. Каждый вызов оператора или функции — это вызов большого количества различных внутренних объектов. Поэтому медлительность Python — это часть его дизайна, и устранить ее совсем не представляется возможным. Можно сказать, что Python — это язык «без ниши». Например, C++ предназначен для высокоэффективной разработки, близкой к железу, Java — для мобильной разработки и энтерпрайз-приложений. Python хорош тем, что имеет приятный синтаксис с низким порогом входа, однако скоростные характеристики делают его непригодным для высокоэффективных продуктов. Но он прекрасно подходит для создания прототипов, небольших скриптов или проверки гипотез. Можно написать код в условиях высокой неопределенности, который потом легко поменять. Это его главные преимущества, а скорость никогда не была основной характеристикой. 

    Владимир Щелов, ведущий разработчик на С/С++ в «Фирме 1С», автор курсов «C++ разработчик», «Fullstack-разработчик на Python» Skillfactory

    Как ускорить Python

    Для ускорения кода Python чаще всего используют:

    • Cython — это специальное расширение Python. С его помощью можно писать код, который выглядит как питон, но при этом включает в себя типизацию и другие конструкции, похожие на C. Cython компилирует код в C, таким образом повышая производительность программы.
    • PyPy — альтернативная реализация языка Python, которая использует метод JIT. PyPy компилирует код в реальном времени, поэтому работает быстрее, чем стандартная реализация Python.
    • Numba еще один компилятор с открытым исходным кодом, переводит код на Python в машинный на лету. 

    Выбор между Cython, PyPy и Numba зависит от проекта и задачи. Например, Cython часто используют для оптимизации библиотек или интеграции с C. PyPy подходит, когда нужно ускорить весь проект, а Numba — для числовых вычислений и обработки массивов.

    Cython — это особое расширение языка. PyPy— альтернативная версия питона, а Numba — набор инструментов для JIT-компиляции, который может быть применен к некоторым функциям программы. Но принцип работы у них похожий: чтобы ускорить Python, нужно транслировать текст программы во что-то другое, чтобы это были не интерпретируемые функции, а скомпилированный заранее код. Это один из обходных маневров, который помогает ускориться.

    Владимир Щелов, ведущий разработчик на С/С++ в «Фирме 1С», автор курсов «C++ разработчик», «Fullstack-разработчик на Python» Skillfactory

     

    Как работает Numba 

    Numba помогает ускорить числовые вычисления. Она делает это с помощью компиляции — превращает код на питоне в машинные команды в режиме реального времени. 

    Нумба хорошо работает с библиотекой NumPy и не требует менять много кода. Чтобы ускориться, нужно просто добавить декоратор @jit перед функцией, которую нужно ускорить. В первый раз этот процесс может занять немного времени, но потом программа будет выполняться быстрее благодаря кэшированию.

    Numba
    Код в Numba. Источник

    Что можно разогнать

    В функциях, скомпилированных с помощью Numba, можно использовать лишь ограниченный набор возможностей Python и Numpy. Есть операторы, функции и классы, которые она понимает, а есть — которые нет. 

    Например, Numba поддерживает:

    • питоновские списки, которые позволяют быстро добавлять элементы в конец (при этом они должны состоять из элементов одного типа);
    • NumPy-массивы, которых нет в стандартной библиотеке Python;
    • кортежи (tuples), которые могут содержать элементы разных типов;
    • типизированные словари из numba.typed с ключами и значениями одного типа (хотя они работают немного медленнее стандартных питоновских словарей);
    • строки (str) и байты (bytes).

    При этом Numba не поддерживает:

    • питоновские словари (dict);
    • списки с разнородными элементами;
    • библиотеки SciPy и Pandas;
    • множества (set);
    • пользовательские классы и объекты Python;
    • функции с динамической типизацией, например принимающие аргументы разных типов;
    • генераторы и итераторы Python;
    • стандартные функции Python, которые не имеют реализации в Numba, особенно те, которые требуют сложной логики или работы с объектами;
    • асинхронные функции (async/await).

    Как использовать Numba 

    Чтобы ускорить код на Python:

    1. Установите Numba через pip install numba или conda install numba. 
    1. Импортируйте библиотеку в свой код.
      from numba import jit

    3. Добавьте декоратор @jit, чтобы ускорить функцию.

    @jit
    
       def my_function(x):
    
           return x * 2

    4. Сделайте вызов функции. Первый запуск займет некоторое время, но потом нумба сохранит скомпилированный код и функция будет выполняться быстрее.

    Сейчас вместо @jit также используют декоратор @njit. При использовании @jit Numba на большой скорости доходит до неподдерживаемых операций, а затем замедляется до обычной скорости Python и сохраняет ее до конца функции. А @njit просто помечает их в качестве исключений. Поэтому этот вариант лучше подходит для достижения максимальной скорости.

    Python, Numba и C++
    Сравнение скорости Python, Numba и C++. Источник

    Векторизация

    Векторизация позволяет нумбе выполнять операцию над несколькими данными одновременно. А еще обрабатывать не один элемент данных за раз, а целые блоки. За счет избавления от явных циклов можно значительно ускорить процесс вычисления. 

    В результате код получается более компактным и понятным. Например, вместо цикла 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]

      

    Векторизация используется, когда нужно работать с массивами данных. Представьте почтовое отделение, которое обрабатывает посылки. Там есть сотрудник, который вручную сортирует коробки, смотрит их, ищет штрих-код. А векторизация — это конвейерная лента, которая автоматически загружает все коробки. При этом важно, чтобы они были одинаковыми и штрих-код располагался в одинаковых местах.

    Владимир Щелов, ведущий разработчик на С/С++ в «Фирме 1С», автор курсов «C++ разработчик», «Fullstack-разработчик на Python» Skillfactory

     

    Главное про ускорение Python с помощью Numba

    • Python — это интерпретируемый язык программирования, у него легкий синтаксис, но низкая производительность.
    • Для ускорения кода Python чаще всего используют расширения и JIT-компиляторы, которые переводят код в машинный вид на лету.
    • Numba — это JIT-компилятор. Для запуска используют декоратор @jit или @njit для достижения максимальной скорости.
    • Numba поддерживает ограниченный набор возможностей Python и Numpy. 
    • Векторизация позволяет обрабатывать не один элемент данных за раз, а целые блоки, что ускоряет процесс вычисления. 

    Разбор

    Поделиться

    Скопировано
    0 комментариев
    Комментарии