2013-07-23 55 views
4

從純粹的性能角度來看,將重複算術運算的結果賦值給變量並在整個代碼中使用該變量通常是最佳做法?或者Python有一些內部緩存結果的方式,並在遇到重複語句時使用它。在Python中的重複算術

例如這是更有效的:

a = 50 
b = a*12-1 
c = a*b 

print c 
#some code 
print c*100 + 10 
#some code 
print c/100 + 20 
#etc 

比這

print 50*(50*12-1) 
#some code 
print 50*(50*12-1) * 100 + 10 
#some code 
print 50*(50*12-1)/100 + 20 
#etc 
+0

你是在談論重複表達式只涉及文字(即固有常數值),就像你上面的例子? –

+2

如果它使您的代碼更易於使用更多變量並且不會使用基準測試產生顯着差異,那麼請使用更具可讀性的代碼。除非你做了非常複雜的計算,否則你可能無法分辨其中的差異。 – korylprince

回答

2

似乎喜歡一個漂亮的可以忽略不計的速度向我走來:

> python -m timeit 'a = 50; b = a*12-1; c = a*b; c; c*100+10; c/100+20;' 
1000000 loops, best of 3: 0.27 usec per loop 
> python -m timeit '50*(50*12-1); 50*(50*12-1) * 100 + 10; 50*(50*12-1)/100 + 20' 
1000000 loops, best of 3: 0.218 usec per loop 

分配稍高於不斷重新計算速度較慢,但因爲korylprince在評論中聲明,分配將導致更容易閱讀代碼。

編輯:我想這是gnibbler在評論的意思,但它仍然比較慢:

> python -m timeit 'def x(): a = 50; b = a*12-1; c = a*b; c; c*100+10; c/100+20;' 'x()' 
1000000 loops, best of 3: 0.428 usec per loop 

EDIT2:其實,這是什麼gnibbler在評論意思,區別還是negligle。關於使用更可讀的評論仍然存在:

> python -m timeit -s 'def x(): a = 50; b = a*12-1; c = a*b; c; c*100+10; c/100+20;' 'x()' 
1000000 loops, best of 3: 0.367 usec per loop 
> python -m timeit -s 'def x(): 50*(50*12-1); 50*(50*12-1) * 100 + 10; 50*(50*12-1)/100 + 20' 'x()' 
1000000 loops, best of 3: 0.278 usec per loop 
+0

全局查找速度較慢。你應該在一個函數內部嘗試這個。 –

+0

類別。您錯過了函數定義的'-s'。我的意思是你也可以在函數中運行僅字面版本來獲得有意義的比較。它看起來較慢的原因是您現在正在添加一個函數開銷。但是由於這些東西通常是在一個函數內部完成的,所以你需要確保你在函數內部對變量查找進行基準測試。 –

+1

如果你使用'dis.dis(x)',你可以看到窺視孔優化器將所有的數學運算都減爲'def x():50 *(50 * 12-1); 50 *(50 * 12-1)* 100 + 10; 50 *(50 * 12-1)/ 100 + 20「(至少在python3.3中) –

0

的文字會更快,只是因爲它沒有提及任何東西。在Python中沒有預處理,所以你不能在C

做的#define像
+0

但是不是每次重新計算表達式50 *(50 * 12-1)? – Bitwise

+0

你知道嗎,我相信我實際上是在我的腦海裏對它進行了預處理,這樣每個50 *(50 * 12-1)的發生率在我的想象中就是29950. :) – hoosierEE

7

我不知道緩存中間結果的任何Python實現。綁定一個局部變量相當便宜,所以經過幾次計算後,它會變得更快。

在唯一不變的是使用的特殊情況下,窺視孔優化器可以減少那些常量

如。

$ python3.3 
Python 3.3.0 (default, Sep 29 2012, 17:17:45)  
[GCC 4.7.2] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> def x(): 
...  50*(50*12-1) 
...  50*(50*12-1) * 100 + 10 
...  50*(50*12-1)/100 + 20 
... 
>>> dis.dis(x) 
    2   0 LOAD_CONST    9 (29950) 
       3 POP_TOP    

    3   4 LOAD_CONST    14 (2995010) 
       7 POP_TOP    

    4   8 LOAD_CONST    19 (319.5) 
      11 POP_TOP    
      12 LOAD_CONST    0 (None) 
      15 RETURN_VALUE   

如果有疑問,更喜歡可讀的版本。微型優化,如果你真的需要那些額外的微秒