Итак, у меня есть критический по времени раздел кода внутри скрипта Python, и я решил написать модуль Cython (с одной функцией - все, что мне нужно), чтобы заменить его.К сожалению, скорость выполнения функции, которую я вызываю из модуля Cython (который я вызываю в своем скрипте Python), не так высока, как я проверял, чтобы быть в различных других сценариях.Обратите внимание, что я не могу поделиться кодом самостоятельно из-за договорного права!Посмотрите следующие случаи и возьмите их в качестве начального описания моей проблемы:
(1) Выполните функцию Cython с помощью интерпретатора Python для импорта модуля и запуска функции.Выполняется относительно быстро (~ 0,04 сек на ~ 100 отдельных тестах, по сравнению с оригинальными ~ 0,24 сек).
(2) Вызов функции Cython внутри скрипта Python на «глобальном» уровне (т.е. не внутри какой-либо функции).Та же скорость, что и в случае (1).
(3) Вызов функции Cython внутри скрипта Python, с функцией Cython внутри главной функции моего скрипта Python;протестировано с функцией Cython в глобальном и локальном пространствах имен, все с той же скоростью, что и case (1).
(4) То же, что (3), но внутри простого цикла for внутри указанной функции Python.Та же скорость, что и в случае (1).
(5) проблема! То же, что и (4), но внутри еще одного цикла for: время выполнения функции Cython (независимо от того, вызывается ли оно глобально или локально)в 10 раз больше, чем в других случаях, и здесь мне нужно вызвать функцию.Ничего странного, чтобы сообщить об этом цикле, и я протестировал все компоненты этого цикла (корректируя / удаляя то, что я мог).Я также попытался использовать цикл while для хихиканья, но безрезультатно.
«Одна вещь, которую мне еще предстоит попробовать, - сделать этот самый внутренний цикл функцией и идти оттуда». РЕДАКТИРОВАТЬ: Только что попробовал - не повезло.
Спасибо за любые ваши предложения - я глубоко сожалею, что не смог поделиться своим кодом ... это немного ранит мою душу, но мойклиент просто не может иметь этот код, плавающий вокруг.Дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить!
- Реальная проблема и первоначальное (некрасивое) решение -
Оказывается, что лучший совет в этом сценарии былочевидный (как обычно): проблема заключалась не в цикле for;с чего бы это?После еще нескольких тестов стало очевидно, что что-то в том, как я вызывал свою функцию Cython, было неправильным, потому что я мог вызывать ее в другом месте (используя входную переменную, отличную от той, которая идет в «настоящую» функцию Cython) без производительностипроблема потерь.
Основная проблема: типы данных.Я написал свою функцию Cython, ожидающую список, полный стандартных чисел с плавающей точкой.К сожалению, мой код сделал это:
function_input = list(numpy_array_containing_npfloat64_data) # yuck.
type(function_input[0]) = numpy.float64
output = Cython_Function(function_input)
внутри функции Cython:
def Cython_Function(list function_input):
cdef many_vars
"""process lots of vars expecting C floats""" # Slowness from converting numpy.float64's --> floats???
type(output) = list
return output
Я знаю, что могу больше поиграться с типами вФункция Cython, которую я очень хорошо могу сделать, чтобы предотвратить «перечисление» существующего массива.В любом случае, вот мое текущее решение:
function_input = [float(x) for x in function_input]
Я приветствую любые отзывы и предложения по улучшению.Массиву function_input numpy на самом деле не нужна точность numpy.float64, но он используется несколько раз, прежде чем перейти к моей функции Cython.