У меня есть следующий цикл for для построения списка значений:
p = 7
A = []
for i in range(0, 10**p):
A.append(i**3 + i**2)
Чтобы ускорить создание списка, я создал его в виде массива Numpy, используя векторизованный подход. Этот подход намного быстрее, чем эквивалентный цикл for, особенно для больших значений p, что увеличивает диапазон.
import numpy as np
from numba import autojit
p = 7
m = np.arange(0, 10**p)
D = np.empty(len(m))
D = m**3 + m**2
Чтобы еще больше ускорить создание массива, я решил попробовать использовать пакет Numba. Ниже моя текущая попытка.
@autojit
def func(a):
a = np.asarray(a)
n = np.arange(0, 10**p)
a = np.append(a, n**3 + n**2)
return a
e = []
E = func(e)
К сожалению, я не вижу никакого прироста производительности от использования Numba, который почти в 3 раза медленнее, чем векторизованный подход, использующий только Numpy.
Любые предложения о том, как использовать Numba для этого?
Ответ 1 · рейтинг 6 · JoshAdel
Numba не делает вызовы произвольных методов быстрее. Если вы обращаетесь к библиотеке, numba в большинстве случаев ничего не может с этим поделать. Но если вы перепишете вещи немного по-другому, вы все равно можете получить приличное ускорение (я использую numba 0.14.0 - если вы используете другую версию, оборудование и т. д., вы можете получить другие результаты, тем более что numba находится в активной разработке):
import numpy as np
import numba as nb
def func(a, p):
a = np.asarray(a)
n = np.arange(0, 10**p)
a = np.append(a, n**3 + n**2)
return a
@nb.jit
def func2(a, p):
a = np.asarray(a)
n = np.empty(10**p, dtype=np.float64)
for k in range(10**p):
n[k] = k*k*(k + 1)
return np.append(a, n)
p = 6
e = []
E = func(e, p)
E2 = func2(e, p)
print np.allclose(E, E2)
И тайминги:
In [51]:
%timeit func(e, p)
10 loops, best of 3: 42.9 ms per loop
In [52]:
%timeit func2(e, p)
100 loops, best of 3: 3.09 ms per loop
Также с p=7 вам нужно быть немного осторожным с числовой точностью.
Ключ с numba заключается в развертывании циклов и выполнении только "примитивных" арифметических вызовов, которые поддерживает numba.