我正在尝试减少使用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数组)。 这些列表包含浮点数,并且具有相同的大小,这是事先已知的。
答案 0 :(得分:2)
有更快的方法进行计算吗?从文本文件中读取和解析列表,并且增加的预处理时间将没有问题(例如创建numpy数组)。这些列表包含浮点数,并且具有相同的大小,这是事先已知的。
PyPy非常擅长优化列表访问,所以你应该坚持使用列表。
有助于PyPy优化事物的一件事是确保您的列表始终只有一种类型的对象。即如果您从文件中读取字符串,请不要将它们放在列表中,然后将它们解析为就地浮点数。相反,使用浮点数创建列表,例如通过在读取每个字符串时解析它们。同样,永远不要尝试预先分配列表,尤其是使用[None,]*N
,否则PyPy将无法guess that all the elements have the same type。
其次,尽可能少地迭代列表。除非PyPy注意到并且可以对其进行优化,否则np_sum
函数会对两个数组进行三次(减法,绝对,求和)。 1.和2.一次走列表,所以它们更快。