Пчему numpy.ndarray медленнее, чем list?
from math import sqrt
import numpy as np
import ctypes
import time
w, h = ctypes.windll.user32.GetSystemMetrics(0),\
ctypes.windll.user32.GetSystemMetrics(1)
arr = np.ndarray((w, h), 'f')
t = time.time()
for ix in range(w):
for iy in range(h):
arr[ix, iy] = sqrt((w/2 - ix)**2+(h/2-iy)**2)
print(time.time()-t)
arr =[[0 for _ in range(w)] for _ in range(h)]
t = time.time()
for ix in range(w):
for iy in range(h):
arr[iy][ix] = sqrt((w/2 - ix)**2+(h/2-iy)**2)
print(time.time()-t)
Ответы (1 шт):
Автор решения: CrazyElf
→ Ссылка
Я попробовал ваш код у себя локально под Windows, а также в Google Colab. И вот что я могу сказать:
Numpyне медленнее, чем ванильныйPython, но и не сильно быстрее, если использовать от Numpy только структуру данных, а весь подход к обработке и все функции при этом брать обычные питоновские, ускорения при этом никакого не будет, конечно- Ваш код ещё и даёт несколько разные результаты при работе с
Numpyи в чистомPython, потому что в первом случае работа идёт сfloat32, а во втором сfloat64и округление при этом получается довольно заметно разным, если просуммировать элементы массивов - Чтобы
Numpyработал заметно быстрее, нужно использовать векторизацию, т.е. работать не с одиночными элементами массива по отдельности, а с целыми строками или столбцами, а лучше сразу с целой матрицей.
Вот я навскидку сделал код с Numpy заметно более быстрым (примерно в 40 раз) и дающим более одинаковый результат в обоих вариантах. Ускорение достигнуто за счёт удаления одного из циклов и использования вместо него векторного вычисления сразу ряда значений с использованием соответствующих функций Numpy:
from math import sqrt
import numpy as np
import ctypes
import time
try:
w, h = ctypes.windll.user32.GetSystemMetrics(0),\
ctypes.windll.user32.GetSystemMetrics(1)
except AttributeError:
w, h = 1536, 864
print(w, h)
arr = np.ndarray((w, h), np.float64)
print(arr.dtype)
t = time.time()
for ix in range(w):
arr[ix, :] = np.sqrt((w/2 - ix)**2+(h/2-np.arange(h))**2)
print(time.time()-t)
print(arr.sum())
arr =[[0 for _ in range(w)] for _ in range(h)]
t = time.time()
for ix in range(w):
for iy in range(h):
arr[iy][ix] = sqrt((w/2 - ix)**2+(h/2-iy)**2)
print(time.time()-t)
print(sum(arr[j][i] for i in range(w) for j in range(h)))
Результат в Google Colab:
1536 864
float64
0.01708245277404785
623787523.1485264
0.7624058723449707
623787523.1485249
Результат под Windows в Jupyter Notebook:
1536 864
float64
0.0567629337310791
623787523.1485264
1.9754235744476318
623787523.1485249