Использование функции для уточнения кода (вместо встроенной лямбды):
def fn(x):
return x-x*d_t+x*x/2*d_t*d_t-x*x*x/6*d_t*d_t*d_t
И функция, объединяющая элементы build_array_recursively
и method2
:
def foo1(length, V_0, function):
returnList = np.empty(length)
returnList[0] = x = V_0
for i in range(1,length):
returnList[i] = x = function(x)
return returnList
In [887]: timeit build_array_recursively(20,0.3, fn);
61.4 µs ± 63 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [888]: timeit method2(20,0.3, fn);
16.9 µs ± 103 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [889]: timeit foo1(20,0.3, fn);
13 µs ± 29.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Основная экономия времени в method2
и foo2
переносит x
, последнее значение, с одной итерации на следующую, вместо индексации с помощью returnList[i-1]
.
Метод накопления, назначение предварительно выделенного массива или добавления в список менее важно. Производительность обычно одинакова.
Здесь вычисления достаточно просты, поэтому детали того, что вы делаете в l oop, сильно влияют на общее время.
Все это циклы. В некоторых ufunc
есть метод reduce
(и accumulate
), который может неоднократно применять функцию к элементам входного массива. np.sum
, np.cumsum
, et c используйте это. Но вы не можете сделать это с помощью общей функции Python.
Вы должны использовать какой-нибудь инструмент компиляции, например numba
, чтобы выполнить l oop намного быстрее.