开发者

Loop control, what is more efficient

Which one of the two alternatives below is more efficient? Any recommendations to further improve it?

Alternative A:

for i in BAR_Items:
    if BAR_Items[i] != A and SHAPE[i+"_S开发者_开发百科HP"] != 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

Alternative 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

Ok, I followed the suggestions and found a way of timing it. After measuring it 500 times, B (0.001279264 seconds) is faster than A (0.001966169 seconds) on average (the numbers are the average).


One of the best ways to test efficiency is with the timeit module. I would put each alternative in a function, run timeit on each function, and compare.


Ok here is a contrived way to look at the performance. Since we are trying to see the difference between using "continue" or pull the code inside the "if block .."

Here is a small experiment.

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)  

Most of the operations are same and here is a small difference:

In case of 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  

In case of 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 

Verdict

Just one OP difference. Really not much right. There are equivalent. Base your decision on readability rather than performance.


For code where performance isn't absolutely critical, ask yourself "which is more understandable" and use that as your answer. A difference of a few microseconds just isn't worth the time to fret over in scripted code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜