【发布时间】:2011-05-13 11:13:20
【问题描述】:
考虑以下类:
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__ 函数占了我的 knn 实现的 90% 的运行时间(谁会想到)。我认为没有任何纯 Python 方法可以加快速度,但也许如果我用 C 实现它?
如果我运行一个简单的 C 程序,它只使用上面的公式计算随机值的距离,它比 Python 快几个数量级。所以我尝试使用 ctypes 并调用一个 C 函数来进行计算,但显然参数和返回值的转换非常昂贵,因为生成的代码要慢得多。
我当然可以在 C 中实现整个 knn 并调用它,但问题是,正如我所描述的,我对向量的某些维度使用不同的距离函数,并且将这些转换为 C 将是太多的工作.
那么我的替代方案是什么?使用Python C-API 编写 C 函数会摆脱开销吗?还有其他方法可以加快计算速度吗?
【问题讨论】:
-
我建议使用 Cython(可能会在几分钟内给出示例实现的答案)。我假设你的算法已经尽可能合理地调整了?
-
@delnan:我已经在可能和适当的情况下使用了缓存,所以我看不到任何节省距离计算的方法。
-
那么……不相关,
dataSample和var是什么? -
@delnan:
datasample是floats的列表,var是来自 numpy 的方差函数。 -
有点跑题了:你确实意识到
__call__()返回的表达式被计算为好像这样写(u - v) ** (2 * self._norm)?请参阅运算符优先级表here。
标签: python performance python-c-api