The Python Oracle

Python if statement efficiency

This video explains
Python if statement efficiency

--

Become part of the top 3% of the developers by applying to Toptal
https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 5 Looping

--

Chapters
00:00 Question
01:22 Accepted answer (Score 51)
01:55 Answer 2 (Score 58)
02:28 Answer 3 (Score 20)
03:46 Answer 4 (Score 9)
04:02 Thank you

--

Full question
https://stackoverflow.com/questions/2539...

Answer 1 links:
[short-circuit evaluation]: http://en.wikipedia.org/wiki/Short-circu...

Answer 3 links:
[The Zen of Python]: http://www.python.org/dev/peps/pep-0020/

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #performance

#avk47



ANSWER 1

Score 62


I would say the single test is as fast as the separate tests. Python also makes use of so called short-circuit evaluation.

That means for (a and b and c), that b or c would not be tested anymore if a is false.

Similar, if you have an OR expression (a or b) and a is true, b is never evaluated.

So to sum up, the clauses don't fail faster with separation.




ACCEPTED ANSWER

Score 52


if statements will skip everything in an else bracket if it evaluates to true. It should be noted that worrying about this sort of problem, unless it's done millions of times per program execution, is called "premature optimization" and should be avoided. If your code is clearer with three if (a and b and c) statements, they should be left in.




ANSWER 3

Score 20


Code:

import dis

def foo():
  if ( a and b and c):
    pass
  else:
    pass

def bar():
  if a:
    if b:
      if c:
        pass

print 'foo():'
dis.dis(foo)
print 'bar():'
dis.dis(bar)

Output:

foo():
  4           0 LOAD_GLOBAL              0 (a)
              3 JUMP_IF_FALSE           18 (to 24)
              6 POP_TOP             
              7 LOAD_GLOBAL              1 (b)
             10 JUMP_IF_FALSE           11 (to 24)
             13 POP_TOP             
             14 LOAD_GLOBAL              2 (c)
             17 JUMP_IF_FALSE            4 (to 24)
             20 POP_TOP             

  5          21 JUMP_FORWARD             1 (to 25)
        >>   24 POP_TOP             

  7     >>   25 LOAD_CONST               0 (None)
             28 RETURN_VALUE        
bar():
 10           0 LOAD_GLOBAL              0 (a)
              3 JUMP_IF_FALSE           26 (to 32)
              6 POP_TOP             

 11           7 LOAD_GLOBAL              1 (b)
             10 JUMP_IF_FALSE           15 (to 28)
             13 POP_TOP             

 12          14 LOAD_GLOBAL              2 (c)
             17 JUMP_IF_FALSE            4 (to 24)
             20 POP_TOP             

 13          21 JUMP_ABSOLUTE           29
        >>   24 POP_TOP             
             25 JUMP_ABSOLUTE           33
        >>   28 POP_TOP             
        >>   29 JUMP_FORWARD             1 (to 33)
        >>   32 POP_TOP             
        >>   33 LOAD_CONST               0 (None)
             36 RETURN_VALUE        

So, although the setup is the same, the cleanup for the combined expression is faster since it leaves only a single value on the stack.




ANSWER 4

Score 9


At least in python, efficiency is second to readability and "Flat is better than nested".

See The Zen of Python