Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка

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

Аватар Олег Борисенков
Отредактировано

Повышаем скорость работы Python с использованием библиотеки Numba и сравниваем с «плюсами» на примере простенького алгоритма.

26К открытий27К показов

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

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

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

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

Увеличиваем скорость работы Python до уровня C++ с Numba 1
Блок-схема алгоритма генерации простых чисел

Реализация на 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, просто установите её через консоль:

			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 и про количество памяти, которое занимают разные типы данных в Python.

Следите за новыми постами
Следите за новыми постами по любимым темам
26К открытий27К показов