У меня есть большой структурированный массив numpy со следующим типом данных:
> my_array.dtype
= dtype([('field1', '<i4', (32,)), ('field2', '<i4', (425,)),
('field3', '<i4', (8021,))])
Моя цель - как можно быстрее получить доступ к любому отдельному элементу.Если я нарежу свой массив по имени поля, Numba сможет работать в не-python-режиме.
@numba.njit
def test_function(my_array_sliced):
for i in range(len(my_array_sliced)):
_ = my_array_sliced[i]
return
> %timeit test_function(my_array['field1'])
399 ns ± 10.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Это работает хорошо, но я понял, что могу добиться лучших результатов с точки зрения производительностидоступ к моему массиву немного по-другому с помощью «постоянного» имени поля:
@numba.njit
def test_function2(my_array):
for i in range(len(my_array)):
_ = my_array[i]['field1']
return
> %timeit test_function2(my_array)
280 ns ± 5.88 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
399нс против 280нс - это большая разница!Я не могу точно сказать, почему есть такая разница.
Если я попытаюсь повысить производительность, добавив параметр в свою функцию, я получу ошибку при печати.
@numba.njit
def test_function3(my_array, v):
for i in range(len(my_array)):
_ = my_array[i][v]
return
> %timeit test_function3(my_array, 0):
TypingError: Failed at nopython (nopython frontend)
Invalid usage of getitem with parameters (Record([('field1', '<i4',
(32,)), ('field2', '<i4', (425,)), ('field3', '<i4', (8021,))]), int64)
То же самое происходит, если я заменяю int-параметр строковым параметром, таким как 'field1' (даже если я не буду использовать строки в первую очередь, потому что Numba на самом деле не имеет с ними дела).
Таким образом, с точки зрения производительности, в настоящее время лучше всего создавать различные функции для каждого имени поля.Это явно безумие.Как мне изменить мой код для достижения максимальной производительности?
Спасибо!