Рассмотрим следующий класс:
class SquareErrorDistance(object):
def __init__(self, dataSample):
variance = var(list(dataSample))
if variance == 0:
self._norm = 1.0
else:
self._norm = 1.0 / (2 * variance)
def __call__(self, u, v): # u and v are floats
return (u - v) ** 2 * self._norm
Я использую его для вычисления расстояния между двумя элементами вектора. Я в основном создаю один экземпляр этого класса для каждого измерения вектора, который использует эту меру расстояния (есть измерения, которые используют другие меры расстояния). Профилирование показывает, что функция __ call __
этого класса составляет 90% времени работы моей knn-реализации (кто бы мог подумать). Я не думаю, что есть какой-либо способ ускорить это на чистом Python, но, может быть, если я реализую его на C?
Если я запустил простую программу на языке C, которая просто вычисляет расстояния для случайных значений с помощью приведенной выше формулы, она будет на порядки быстрее, чем Python. Поэтому я попытался использовать ctypes и вызвать функцию C, которая выполняет вычисления, но, очевидно, преобразование параметров и возвращаемых значений обходится слишком дорого, потому что результирующий код намного медленнее.
Я мог бы, конечно, реализовать весь knn в C и просто вызвать его, но проблема в том, что, как я описал, я использую разные функции расстояния для некоторого измерения векторов и переводю это было бы слишком много работы для C.
Итак, каковы мои альтернативы? Избавится ли написание C-функции с помощью Python C-API от накладных расходов? Есть ли другие способы ускорить этот расчет?