Увеличиваем скорость работы Python до уровня C++ с Numba

Kate

Administrator
Команда форума
В этой статье автор разобрался, как увеличить скорость работы Python, и продемонстрировал реализацию на реальном примере.

Прим. ред. Это перевод. Мнение редакции может не совпадать с мнением автора оригинала.

Тест базовой скорости​

Для сравнения базовой скорости Python и C++ я буду использовать алгоритм генерации случайных простых чисел.

Блок-схема алгоритма генерации случайных чисел
Блок-схема алгоритма генерации простых чисел

Реализация на Python​

import math
from time import per_counter
def is_prime(num):
if num == 2:
return True;
if num <= 1 or not num % 2:
return False
for div in range(3,int(math.sqrt(num)+1),2):
if not num % div:
return False
return True
def run program(N):
for i in range(N):
is_prime(i)
if __name__ == ‘__main__’:
N = 10000000
start = perf_counter()
run_program(N)
end = perf_counter()
print (end — start)

Реализация на C++​

#include
#include
#include
using namespace std;
bool isPrime(int num)
{
if (num == 2) return true;
if (num <= 1 || num % 2 == 0) return false;
double sqrt_num = sqrt(double(num));
for (int div = 3; div <= sqrt_num; div +=2){
if (num % div == 0) return false;
}
return true;
}
int main()
{
int N = 10000000;
clock_t start,end;
start = clock();
for (int i; i < N; i++) isPrime(i);
end = clock();
cout << (end — start) / ((double) CLOCKS_PER_SEC);
return 0;
}

Результат​

  • Python: скорость выполнения 80,137 секунд;
  • C++: скорость выполнения 3,174 секунды.

Комментарий​

Как и ожидалось, программа на C++ выполняется в 25 раз быстрее, чем на Python. Ожидания подтвердились, потому что:

  • Python — это динамически типизированный язык;
  • GIL(Global Interpreter Lock) — не поддерживает параллельное программирование.
Благодаря тому, что Python это гибкий универсальный язык, наш результат можно улучшить. Один из лучших способов увеличить скорость Python — Numba.

Numba​

Numba — это Open Source JIT-компилятор, который переводит код на Python и NumPy в быстрый машинный код.
Чтобы начать использовать Numba, просто установите её через консоль:

pip install numba

Реализация на Python с использованием Numba​

import math
from time import per_counter
from numba import njit, prange
@njit(fastmath=True, cache=True)
def is_prime(num):
if num == 2:
return True;
if num <= 1 or not num % 2:
return False
for div in range(3,int(math.sqrt(num)+1),2):
if not num % div:
return False
return True
@njit(fastmath=True, cache=True,parallel=True)
def run program(N):
for i in prange(N):
is_prime(i)
if __name__ == ‘__main__’:
N = 10000000
start = perf_counter()
run_program(N)
end = perf_counter()
print (end — start)
***

Как вы могли заметить, в коде добавились декораторы njit:

  • parallel=True — включает параллельное выполнение программы на процессоре;
  • fastmath=True — разрешает использование небезопасных преобразований с плавающей точкой;
  • cache=True— позволяет сократить время компиляции функции, если она уже была скомпилирована.

Итоговая скорость Python​

  • Python: скорость выполнения 1,401 секунды;
  • C++: скорость выполнения 3,174 секунды.
Теперь вы знаете что Python способен обогнать C++. О других способах увеличения скорости работы Python читайте в статье про пять проектов, которые помогают ускорить код на Python.

Источник статьи: https://tproger.ru/translations/python-mozhet-byt-bystree-c/
 
Сверху