Мы можем сделать Python для циклов намного быстрее.
Вопрос автора был о том, почему Python "для циклов" такой медленный по сравнению с C # и JavaScript.Это не решается путем разработки другого алгоритма, который уменьшает потребность в «циклах for» (особенно с учетом того, что версии C # и JavaScript также будут быстрее с измененным алгоритмом).В общем, языки программирования сравниваются с использованием аналогичных алгоритмов с их различием, допускаемым языковыми особенностями, которые позволяют им преуспеть в задаче - https://benchmarksgame - https://benchmarksgame -team.pages.debian.net/benchmarksgame/index.html
В этом случае задача состоит в том, чтобы использовать возможности языка Python для более быстрого поиска по миллиарду чисел (размер трех вложенных циклов)?
Для ускорения кода были испробованы два подхода: Cython и Numba (отдельно).
Настройка:
- Jupyter Notebooks
- Python 3.5.2 OS
- Windows 10 64-разрядная
- Процессор i7
Результаты:
- Python 3.5.2 => 387.356 секунд
- Cython => 117,223 секунды
- Cython (улучшено) => 0,63 секунды (с использованием предложения @CodeSurgeon)
- Numba => 0,5 секунды
версия Numbaсопоставимо с JavaScript и C # раз.Numba обеспечил 774 ускорения по Pure Python, используя тот же «неоптимальный» алгоритм.Обратите внимание, что все три реализации в основном используют один и тот же код, как показано ниже.
- Код Python 3.5.2
import time
def solve():
for c in range(1000, 0, -1):
for a in range(1000, 0, -1):
for b in range(1000, 0, -1):
if (a*a)+(b*b)==(c*c):
if a+b+c == 1000:
return a*b*c
to = time.time()
print('I have found it {}'.format(solve()))
print("Elapsed Time\n", time.time()- t0)
Python 3.5.2 Вывод
I have found it 31875000
Elapsed Time
387.3550021648407
Cython Code (см.
https://ipython -books.github.io / 55-ускоряющийся-python-код-с-cython / )
%load_ext cython
%%cython -a
import time
def solve():
for c in range(1000, 0, -1):
for a in range(1000, 0, -1):
for b in range(1000, 0, -1):
if (a*a)+(b*b)==(c*c):
if a+b+c == 1000:
return a*b*c
t0 = time.time()
print('I have found it {}'.format(solve()))
print("Elapsed Time\n", time.time()- t0)
Cython Output
I have found it 31875000
('Elapsed Time\n', 117.22299981117249)
Cython (с Cdef https://buildmedia.readthedocs.org/media/pdf/notes-on-cython/latest/notes-on-cython.pdf)
%% cython -a
время импорта
cdef int solve (): cdef int a, b,c
for c in range(1000, 0, -1):
for a in range(1000, 0, -1):
for b in range(1000, 0, -1):
if (a*a)+(b*b)==(c*c):
if a+b+c == 1000:
return a*b*c
t0 = time.time () print ('Я нашел его {}'. format (solve ())) print ("Истекшее время \ n", time.time () -t0)
Вывод (Cython с использованием Cdef)
I have found it 31875000
('Elapsed Time\n', 0.6340005397796631)
Код Numba (см.
https://numba.pydata.org/)
import time
from numba import jit
@jit(nopython=True) # only need to add Numba decorator to get speed up
def solve():
for c in range(1000, 0, -1):
for a in range(1000, 0, -1):
for b in range(1000, 0, -1):
if (a*a)+(b*b)==(c*c):
if a+b+c == 1000:
return a*b*c
t0 = time.time()
print('I have found it {}'.format(solve()))
print("Elapsed Time\n", time.time()- t0)
Выход Numba
I have found it 31875000
Elapsed Time
0.5209996700286865