2010-11-04 160 views
1

以下兩種替代方案中的哪一種更高效?任何建議,以進一步改善它?循環控制,什麼是更高效

備選方案A:

for i in BAR_Items: 
    if BAR_Items[i] != A and SHAPE[i+"_SHP"] != A: continue 
    if i in Selection: 
     Selection.remove(i) 
     BAR_Items[i].clearActions() 
     BAR_Items[i].add(vizact.spinTo(axisAngle=[0,1,0,90],speed=300)) 
     VFrame.SetStatusText(frame, i + " has been deselected. "+ str(Selection)) 
    else: 
     Selection.append(i) 
     BAR_Items[i].add(vizact.spin(0,1,0,90,viz.FOREVER)) 
     VFrame.SetStatusText(frame, i + " selected. " + str(Selection)) 
    break 

替代B:

for i in BAR_Items: 
    if BAR_Items[i] == A or SHAPE[i+"_SHP"] == A: 
     if i in Selection: 
      Selection.remove(i) 
      BAR_Items[i].clearActions() 
      BAR_Items[i].add(vizact.spinTo(axisAngle=[0,1,0,90],speed=300)) 
      VFrame.SetStatusText(frame, i + " has been deselected. "+ str(Selection)) 
     else: 
      Selection.append(i) 
      BAR_Items[i].add(vizact.spin(0,1,0,90,viz.FOREVER)) 
      VFrame.SetStatusText(frame, i + " selected. " + str(Selection)) 
     break 

好的,我隨後的建議,並發現它的定時的方法。測量500次後,B(0.001279264秒)比A(0.001966169秒)平均快(數字是平均值)。

+2

當你測量它們時,你學到了什麼?請包含運行這些信息的時間信息。 – 2010-11-04 21:33:26

+0

@ S.Lott:@relima:除特殊情況外,它會運行嗎?從列表中使用索引和項目是錯誤的。 – pyfunc 2010-11-04 21:38:56

+0

@pyfunc:「它會運行嗎?」?很重要。所有「什麼是更有效率」的問題都應該包括以下指標:(a)實際運行和(b)哪個更有效。 – 2010-11-04 21:41:03

回答

3

好吧,這裏是一個人爲的方式來看看錶現。由於我們試圖看到使用「繼續」或在「如果塊」內部拉代碼之間的差別,因此我們將嘗試使用這些代碼。

這是一個小實驗。

def f(): 
    x = {'a':'b', 'c':'d', 'e':'d'} 
    for l in x: 
     if x[l] != 'd': continue 
     print x 

def f1(): 
    x = {'a':'b', 'c':'d', 'e':'d'} 
    for l in x: 
     if x[l] == 'd': 
      print x  

import dis 
print dis.dis(f) 
print dis.dis(f1) 

大多數操作是相同的,這裏是一個小的差異:

則F的情況下:

56 POP_TOP    
57 JUMP_ABSOLUTE   34 
60 JUMP_FORWARD    1 (to 64) 
63 POP_TOP    

64 LOAD_FAST    0 (x) 
67 PRINT_ITEM   
68 PRINT_NEWLINE  
69 JUMP_ABSOLUTE   34 
72 POP_BLOCK   
73 LOAD_CONST    0 (None) 
76 RETURN_VALUE 

在F1的情況下:

56 POP_TOP    

57 LOAD_FAST    0 (x) 
60 PRINT_ITEM   
61 PRINT_NEWLINE  
62 JUMP_ABSOLUTE   34 
65 POP_TOP    
66 JUMP_ABSOLUTE   34 
69 POP_BLOCK   
70 LOAD_CONST    0 (None) 
73 RETURN_VALUE 

判決

只有一個OP差異。真的不太合適。有相同的。根據您的可讀性而不是性能做出決定。

+0

我的Bar_items實際上是一個返回對象的字典。 A是它與之比較的對象。 – relima 2010-11-04 21:43:59

+0

@relima:哦,我! – pyfunc 2010-11-04 21:45:02

+0

這太棒了。感謝您的辛勤工作。 – relima 2010-11-04 22:03:08

5

測試效率的最佳方法之一是使用timeit模塊。我會把每個選項放在一個函數中,在每個函數上運行timeit並進行比較。

0

對於性能不是絕對關鍵的代碼,問問自己「哪個更容易理解」,並將其用作答案。只有幾微秒的差距不值得花時間在腳本代碼中煩惱。

+1

到目前爲止,我的程序由於這種微小的差異而使我的opengl刷新率從90fps降低到45 fps,這種差異至今仍然存在。 – relima 2010-11-04 22:42:52

+0

現在,在我的階段,這不是很麻煩,但是當我嘗試呈現大量的動畫對象時,它肯定會影響我。 – relima 2010-11-04 22:45:00

+0

@relima:你真的只是說只通過添加continue語句,你的刷新率提高了100%嗎?根據pyfunc的回答,差異是一個操作碼。即使運行數百萬次,我也不知道它會如何產生這種效果。無論如何,在執行關鍵代碼時,「哪個更快」的唯一答案是定時自己的代碼。 – 2010-11-05 16:38:53