2012-01-11 47 views
1

我需要函数聚合器,它将两个列表减少为一个总数。 '物品'应该是布尔人的矢量。Python;实现按元素向量乘法的最高性能方法

所以,我写这些功能:

def element_wise_multiplication(weights, items): 
    return map(lambda x, y: x * y, weights, items) 

def total(weights, items): 
    return sum(element_wise_multiplication(weights, items)) 

他们看起来OK我,但问题是,探查表明,随着它拉姆达行负责运行的95%,所以它的性能几乎不可接受。

什么是最有效的实现方法?

P.S.我知道NumPy的数组,但我想在这个上使用PyPy。或者在这种情况下使用它不值得吗?

+1

在PyPy上,只需要在简单的循环中编写它就会好得多。再加上你的代码会更具可读性。 – fijal 2012-01-12 12:14:47

回答

3

可以照顾与发电机像这样:

from itertools import izip 
value = sum((x * y) for x, y in izip(weights, items)) 

izip完成同样的事情内置zip,但是没有内存高架。

+1

当然,内存开销更高,但是... value = sum([(x * y)for x,y in izip(权重,项目)])'实际上更快:) – 2012-01-11 22:51:36

+0

这给了24%的优化。有什么机会进一步推动它? – Zotov 2012-01-11 22:53:10

+0

@RicardoCárdenes谢谢!优化47%。这还差不多) – Zotov 2012-01-11 23:01:50

1

尝试只是这样的:

def total(weights, items): 
    return sum (x * y for x, y in zip(weights, items)) 
2

虽然你提到不希望在这种情况下使用numpy,但可能值得关注速度差异。

最好的非numpy解决方案似乎是一个使用izip的发电机,这个发电机勉强超过了zip。

In [31]: %timeit sum(x*y for x,y in zip(weights,items)) 
    10000 loops, best of 3: 158 us per loop 

    In [32]: %timeit sum(x*y for x,y in izip(weights,items)) 
    10000 loops, best of 3: 125 us per loop 

但是当我们使用numpy的阵列,我们得到:

In [33]: %timeit (np_weights,np_items).sum() 
    100000 loops, best of 3: 9.08 us per loop 

的numpy的解决方案是快了整整14倍。如果这真的是你的代码中的瓶颈,那么numpy就是要走的路。