4

在 itertools 模块的文档中,我发现了这条评论

def dotproduct(vec1, vec2):
    return sum(imap(operator.mul, vec1, vec2))

请注意,可以通过将全局查找替换为定义为默认值的局部变量来优化上述许多方法。例如,点积配方可以写成:

def dotproduct(vec1, vec2, sum=sum, imap=imap, mul=operator.mul):
    return sum(imap(mul, vec1, vec2))

如何?。
是否有实际的明显加速(可以平衡较大函数签名的不便)?
如图所示,在哪些特定条件下使用局部变量是相关的?

编辑:我用 timeit 进行了测试,并且有任何相关的差异。
对于两个 40 项列表作为 vec1、vec2:

全局查找-> 3.22720959404
本地查找-> 3.19884065683

也就是说,只有大约。1% 的收益。

4

1 回答 1

2

是否有实际的明显加速(可以平衡较大函数签名的不便)?

我非常怀疑它,因为在原始定义中每个查找都发生一次。请注意,您已经更改了函数的含义。

在哪种特定条件下,在所示案例中使用局部变量是相关的?

只有在一个紧密的循环内;在这种情况下,如果dot_product用于说一个非常大的矩阵乘法(无论如何你不会在纯 Python 中这样做,更不用说使用迭代器了)。

编辑:我刚刚反汇编了这两个函数,但我的预感是错误的,尽管我的观点仍然成立:

>>> def dotproduct(vec1, vec2):
...     return sum(imap(operator.mul, vec1, vec2))
...
>>> dis.dis(dotproduct)
  2           0 LOAD_GLOBAL              0 (sum)
              3 LOAD_GLOBAL              1 (imap)
              6 LOAD_GLOBAL              2 (operator)
              9 LOAD_ATTR                3 (mul)
             12 LOAD_FAST                0 (vec1)
             15 LOAD_FAST                1 (vec2)
             18 CALL_FUNCTION            3
             21 CALL_FUNCTION            1
             24 RETURN_VALUE
>>> def dotproduct(vec1, vec2, sum=sum, imap=imap, mul=operator.mul):
...     return sum(imap(mul, vec1, vec2))
...
>>> dis.dis(dotproduct)
  2           0 LOAD_FAST                2 (sum)
              3 LOAD_FAST                3 (imap)
              6 LOAD_FAST                4 (mul)
              9 LOAD_FAST                0 (vec1)
             12 LOAD_FAST                1 (vec2)
             15 CALL_FUNCTION            3
             18 CALL_FUNCTION            1
             21 RETURN_VALUE
于 2011-07-17T16:38:24.300 回答