Python pypy:绝对数组/向量差的有效总和

时间:2014-06-01 18:38:20

标签: python performance numpy vector pypy

我正在尝试减少使用pypy运行的脚本的计算时间。 它必须为大量列表/向量/数组计算绝对差的成对和。 输入向量的长度非常小,在10到500之间。 到目前为止,我测试了三种不同的方法:

1)天真的方法,输入为列表:

def std_sum(v1, v2):
distance = 0.0
for (a,b) in izip(v1, v2):
     distance += math.fabs(a-b)
 return distance

2)使用lambdas和reduce,输入为list:

lzi = lambda v1, v2: reduce(lambda s, (a,b):s + math.fabs(a-b), izip(v1, v2), 0)
def lmd_sum(v1, v2):
    return lzi(v1, v2)

3)使用numpy,输入为numpy.arrays:

def np_sum(v1, v2):
    return np.sum(np.abs(v1-v2))

在我的机器上,使用pypy和itertools.combinations_with_replacement中的对 在500个这样的列表中,前两种方法非常相似(大约5秒), 虽然numpy方法明显变慢,大约需要12秒。

有更快的方法进行计算吗?列表从文本中读取和解析 文件和增加的预处理时间都没有问题(例如创建numpy数组)。 这些列表包含浮点数,并且具有相同的大小,这是事先已知的。

我用于''基准测试的脚本''可以找到here和一些示例数据here

1 个答案:

答案 0 :(得分:2)

  

有更快的方法进行计算吗?从文本文件中读取和解析列表,并且增加的预处理时间将没有问题(例如创建numpy数组)。这些列表包含浮点数,并且具有相同的大小,这是事先已知的。

PyPy非常擅长优化列表访问,所以你应该坚持使用列表。

有助于PyPy优化事物的一件事是确保您的列表始终只有一种类型的对象。即如果您从文件中读取字符串,请不要将它们放在列表中,然后将它们解析为就地浮点数。相反,使用浮点数创建列表,例如通过在读取每个字符串时解析它们。同样,永远不要尝试预先分配列表,尤其是使用[None,]*N,否则PyPy将无法guess that all the elements have the same type

其次,尽可能少地迭代列表。除非PyPy注意到并且可以对其进行优化,否则np_sum函数会对两个数组进行三次(减法,绝对,求和)。 1.和2.一次走列表,所以它们更快。