2010-11-04 115 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