2011-07-17 103 views
4

在了itertools模塊裏的文檔,我發現這條評論設置局部變量的函數,而不是使用全局優化功能

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

注意,許多上述配方可以通過替換全局優化 將局部變量定義爲默認值的查找。例如, 的dotproduct配方可以寫爲:

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

怎麼回事?
是否有一個實際明顯的加速(可以平衡較大功能簽名的不便)?
在哪些特定條件下,使用案例中的局部變量如所示那樣是相關的?

編輯:我用timeit測試過,並且有任何相關的區別。
對於兩個40項的列表作爲VEC 1,VEC 2:

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

也就是說,只有約1%的收益。

+0

如果你打電話的時間一致的方法數量龐大,可以考慮創建一個別名'FUNC = module.func'以防止每次引用該方法時在模塊中查找。雖然我不會覺得麻煩,但我從來沒有發現它明顯更快,而且通常只會讓代碼更難閱讀。爲自己測試並決定。 – tomasz

+1

我真的很討厭那個具體的例子。假設有人誤將'dotproduct((1,2),(3,4))'作爲'dotproduct(1,2,3,4)'(當我將一些參數傳遞給一個真正期望的單個參數是一個值列表)。在第一個定義中,用戶會得到一個TypeError來傳遞錯誤的參數數量。在第二個定義中,用戶會默默覆蓋'sum'和'imap'。至少可以說這是令人驚訝的。 –

+1

1%的收益並不是顯着差異;它可以 (!)如果在輸入尺寸向無窮大方向增長時保持1%,那麼它的效果會很顯着,但是NumPy確實能夠將產品的點數加快幾個數量級。我不會爲了這樣一個小小的好處而改變界面。這是過早的優化。 –

回答

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 
+0

「請注意,您已更改函數的含義」不確定你的意思。你能解釋一下嗎? – joaquin

+2

默認的操作符只能被讀取一次(否則這不會作爲優化工作)。因此,如果您以後更改其中一個,則不會注意到這一點。現在在這裏顯然不太可能,但仍值得記住 – Voo

+0

@joaquin:Voo說的,再加上從兩個變到五個變量的更根本的變化。 –