Ускорение кода Python с помощью Nim

Python - один из самых популярных и доступных языков программирования всех времен, но далеко не самый быстрый. Многие создатели библиотек и фреймворков прибегали к использованию расширений C, чтобы их код работал быстрее, чем собственный Python. Хотя это работает достаточно хорошо, для тех, кто не знаком с C, это ад на земле управлять сборкой мусора и безопасностью памяти. И здесь на помощь приходит Ним.

Что такое Ним?

Это статически типизированный компилируемый объектно-ориентированный язык программирования. Nim создавался таким же быстрым, как C, выразительным, как Python, и таким же расширяемым, как Lisp. Благодаря схожести синтаксиса с Python, это прекрасный выбор для языка расширения, когда C вам не по душе.

Начало работы с Нимом

Чтобы начать писать код Nim, вам сначала нужно установить его в своей системе. Для этого перейдите на nim-lang.org, скачайте и установите его.

Когда вы закончите, давайте напишем ваши первые строчки кода Nim. Сначала мы создадим наш файл, я назову свой hello.nim, вы можете называть свой как хотите. Теперь откроем его любым текстовым редактором и напишем следующее:

echo("Hello, world!")

Сохраните и закройте файл, затем откройте командную строку в месте расположения файла и введите:

nim compile hello.nim

И вуаля! "Привет, мир!" должен был быть напечатан на консоли. Это для вас основы Nim, теперь давайте перейдем к основной теме этой статьи.

Встраивание Nim в приложения Python

Nim поставляется с предустановленным модулем nimpy, а для Python доступен модуль nimporter. Последний можно установить с помощью pip install nimporter. Это два пакета, которые будут необходимы при совместной работе с этими языками.

Чтобы продемонстрировать возможности Nim, мы создадим простой тест, сравнивающий скорости обоих языков, используя простую функцию, которая находит n-е число последовательности Фибоначчи.

Давайте создадим папку с именем Benchmark с тремя файлами внутри:

  • main.py - файл, который мы будем запускать
  • nmath.nim - файл, содержащий версию Nim нашей fib функции.
  • pmath.py - файл, содержащий версию Python нашей fib функции.

Во-первых, давайте напишем нашу fib функцию в pmath.py

def fib(n):
    if n == 0:
        return 0
    elif n < 3:
        return 1
    return fib(n - 1) + fib(n - 2)

Перейдем к nmath.nim. Во-первых, нам нужно импортировать nimpy следующим образом:

import nimpy

Прямо как Python, правда? Теперь о самой функции:

import nimpy

proc fib(n: int): int {.exportpy.} =
    if n == 0:
        return 0
    elif n < 3:
        return 1
    return fib(n-1) + fib(n-2)

Давайте разберемся с этим.

Мы определяем функцию fib с помощью ключевого слова proc. Мы указываем возвращаемый тип как целое число, и Woah! Что это за чудовище? {.exportpy.} сигнализирует Ниму, что эта функция предназначена для использования в другом модуле Python. В остальном все точно так же, как и в Python.

Бенчмаркинг

В main.py мы собираемся создать простой тест:

import nimporter
from time import perf_counter
import nmath  # Nim imports!
import pmath
print('Measuring Python...')
start_py = perf_counter()
for i in range(0, 40):
    print(pmath.fib(i))
end_py = perf_counter()

print('Measuring Nim...')
start_nim = perf_counter()
for i in range(0, 40):
    print(nmath.fib(i))
end_nim = perf_counter()

print('---------')
print('Python Elapsed: {:.2f}'.format(end_py - start_py))
print('Nim Elapsed: {:.2f}'.format(end_nim - start_nim))

Вот и все!

Пакет nimporter разрешает импорт Nim в обычные модули Python, которые можно использовать так же, как нативные. Круто, правда?

Чтобы запустить код, введите обычную команду python main.py в командную строку и наблюдайте!

Python Elapsed: 33.60
Nim Elapsed: 1.05

Резюме

И это все, что нужно для встраивания Nim в Python. Nim оказался примерно в 30 раз быстрее, хотя имейте в виду, что разница в скорости может варьироваться в зависимости от выполняемой задачи. Чтобы лучше узнать Нима, я настоятельно рекомендую просмотреть официальную документацию и почитать в Википедии.

Хорошо, это все для урока! Спасибо, что терпел меня до конца. Если вы нашли статью полезной, оставьте несколько аплодисментов!