First, let's put your code(s) in a function
def func(): # line 1
x = 'hello joe' # line 2
if x == 'hello': # line 4
print('nope') # line 5
else: # line 6
if x == 'hello joe': # line 7
print(x) # line 8
now disassemble with that (using CPython 3.4):
import dis
dis.dis(func)
we get:
2 0 LOAD_CONST 1 ('hello joe')
3 STORE_FAST 0 (x)
4 6 LOAD_FAST 0 (x)
9 LOAD_CONST 2 ('hello')
12 COMPARE_OP 2 (==)
15 POP_JUMP_IF_FALSE 31
5 18 LOAD_GLOBAL 0 (print)
21 LOAD_CONST 3 ('nope')
24 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
27 POP_TOP
28 JUMP_FORWARD 25 (to 56)
7 >> 31 LOAD_FAST 0 (x)
34 LOAD_CONST 1 ('hello joe')
37 COMPARE_OP 2 (==)
40 POP_JUMP_IF_FALSE 56
8 43 LOAD_GLOBAL 0 (print)
46 LOAD_FAST 0 (x)
49 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
52 POP_TOP
53 JUMP_FORWARD 0 (to 56)
>> 56 LOAD_CONST 0 (None)
59 RETURN_VALUE
now change to elif:
2 0 LOAD_CONST 1 ('hello joe')
3 STORE_FAST 0 (x)
4 6 LOAD_FAST 0 (x)
9 LOAD_CONST 2 ('hello')
12 COMPARE_OP 2 (==)
15 POP_JUMP_IF_FALSE 31
5 18 LOAD_GLOBAL 0 (print)
21 LOAD_CONST 3 ('nope')
24 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
27 POP_TOP
28 JUMP_FORWARD 25 (to 56)
6 >> 31 LOAD_FAST 0 (x)
34 LOAD_CONST 1 ('hello joe')
37 COMPARE_OP 2 (==)
40 POP_JUMP_IF_FALSE 56
7 43 LOAD_GLOBAL 0 (print)
46 LOAD_FAST 0 (x)
49 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
52 POP_TOP
53 JUMP_FORWARD 0 (to 56)
>> 56 LOAD_CONST 0 (None)
59 RETURN_VALUE
The only differences are the line numbers.
else: # line 6
if x == 'hello joe': # line 7
becomes (and shifts the rest as well)
elif x == 'hello joe': # line 6
There are as many instructions in both versions. The else
and if
keywords in that case seem to have been converted exactly the same way as elif
. Not guaranteed in all implementations. Personally I'd stick to the shortest code (elif
) because it's more "meaningful" and if a code should be faster, it would probably be that one.