2013-07-20 193 views
1

我正在優化一個我遇到速度問題的python程序。 我在另一份文件上播放出現在我的程序中的各種可能影響執行速度的文件。爲什麼a + = x比a = a + x慢?

我發現:

a = 0 
for x in range(10000000): 
    a += x 
return a 

比稍慢:

a = 0 
for x in range(10000000): 
    a = a + x 
return a 

第一腳本需要幾秒鐘1.5和1.55之間執行,而第二個需要regulary約1,36-1.37秒(使用cProfile)。

任何想法,爲什麼這可能是?謝謝:)

+0

'dis.dis()'說什麼?我覺得'a + = x'應該稍微快一點 –

+0

就地版本稍微慢一點,因爲'int'沒有定義自己的原地添加,即'int'的槽'nb_inplace_add'爲'0'。請參閱http://hg.python.org/releasing/3.3.1/file/8e5812b35480/Objects/longobject.c#l4918 – nymk

回答

11

使用timeit module做適當的時間。它避免了常見的缺陷,爲您的平臺使用最精確的計時器實現,並通過重複測試代碼許多次,儘量減少操作系統調度的影響。

另一方面,使用探查器會增加大量開銷以支持完整的調用堆棧; timeit測量完整的執行時間,而不是堆棧中的單個調用。

使用timeit顯示了這兩個版本都分不出(默認爲1百萬次迭代):

>>> timeit.timeit('a += x', 'a = x = 1') 
0.047940969467163086 
>>> timeit.timeit('a = a + x', 'a = x = 1') 
0.04770612716674805 

這兩種操作都一個字節碼:

>>> def f(): a += x 
... 
>>> def g(): a = a + x 
... 
>>> import dis 
>>> dis.dis(f) 
    1   0 LOAD_FAST    0 (a) 
       3 LOAD_GLOBAL    0 (x) 
       6 INPLACE_ADD   
       7 STORE_FAST    0 (a) 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   
>>> dis.dis(g) 
    1   0 LOAD_FAST    0 (a) 
       3 LOAD_GLOBAL    0 (x) 
       6 BINARY_ADD   
       7 STORE_FAST    0 (a) 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   
+0

您能否簡單解釋一下爲什麼'timeit'更好? – contradictioned

+0

這是澄清,謝謝。可能我的時機出錯了,下次我會用'timeit'。 – Pabce

0

a += x基本上不是一個增量操作。您將再次將變量a + x分配給a。這與分配a = a + x變量的值幾乎相同。

正如皮特斯所說,沒有理由在時間上有這樣的差距。

+++++編輯到DSM

整數在Python是不可改變的:你增加a,如果你增加b如果定義

a = 5

b = 5

以便'增加'b,你必須'重新分配'它b,這就是我的意思。

+0

我不確定你說'a + = x'不是增量操作。它與'a = a + x'不一樣,它們使用不同的特殊方法,'__add__'和'__iadd__'。原則上他們可以做完全不同的事情。 – DSM

+0

啊,現在你已經明確指出你特指整數情況,而不是一般的「a + = x」操作。 – DSM

相關問題