Оптимизируйте PyFloat_FromDouble, Pyx_GetItemInt и PyObject_RichCompare в сгенерированном Cython коде C

avatar
The Unfun Cat
8 апреля 2018 в 08:33
610
1
0

Я пытаюсь написать арифметическую библиотеку кодирования длин серий для Python на Cython. Ниже вы видите, как выглядит объявление и важные части горячего цикла алгоритма. В нем есть два места с большим и умеренным взаимодействием с Python, строки 73-74 и 77. Код C, сгенерированный для части с тяжелым взаимодействием с Python, показан на рисунке в конце. Я спрошу здесь только о том, как решить 73-74, так как думаю, что исправление для 77 будет аналогичным.

Как видите, 1) в сгенерированном коде C используется много типов, 2) используется richcompare и 3) getitemint. Я не понимаю, почему: 1) типы должны быть одинаковыми, 2) сравнение должно быть возможно на уровне C, поскольку они просто сравнивают одни и те же типы чисел и 3) getitem должен быть излишним, поскольку вы просто ищете индекс в массиве C.

Как это исправить, чтобы оптимизировать мой код? Является ли проблема в том, что объявления массива numpy создают объекты Python и что мне нужно каким-то образом указать на них указатель?

enter image description here

Здесь вы видите код C, сгенерированный Cython для двух темных и светло-желтых мест в моем горячем цикле:

enter image description here

Источник

Ответы (1)

avatar
DavidW
8 апреля 2018 в 08:40
5

Вы не ввели nvs или nrs, поэтому они рассматриваются как объекты Python (и, следовательно, nv должны быть преобразованы в объект Python для сравнения).

Выполнить:

cdef long[:] nrs = np.zeros( # ... as before
cdef double[:] nvs = np.zeros( # ... as before

(Кроме того, хотя изображения html полезны, было бы намного легче читать, если бы вы также включили код в виде текста...)

The Unfun Cat
8 апреля 2018 в 08:41
0

Да, я только что думал об этом; также изображения не являются google/hooliable.

DavidW
8 апреля 2018 в 08:43
1

Я определенно понимаю значение выделения, хотя. Но для меня в основном они не копируемые — я не могу быстро получить код в редакторе и изменить его.

ead
8 апреля 2018 в 18:56
2

@TheUnfunCat Я бы рекомендовал использовать long[::1] nrs=... также для подписи функции. Это дает понять, что память является непрерывной, что приводит к генерации более эффективного кода, см., например, coderhelper.com/q/49058949/5769463