Python & Numba: максимально быстрый доступ к элементам структурированного массива - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть большой структурированный массив 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 на самом деле не имеет с ними дела).

Таким образом, с точки зрения производительности, в настоящее время лучше всего создавать различные функции для каждого имени поля.Это явно безумие.Как мне изменить мой код для достижения максимальной производительности?

Спасибо!

...