I recently answered a question on a sister site which asked for a function that counts all even digits of a number. One of the other answers contained two functions (which t
If we use dis.dis(), we can see how the functions actually behave.
count_even_digits_spyr03_for():
7 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (count)
8 6 SETUP_LOOP 42 (to 51)
9 LOAD_GLOBAL 0 (str)
12 LOAD_GLOBAL 1 (n)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
18 GET_ITER
>> 19 FOR_ITER 28 (to 50)
22 STORE_FAST 1 (c)
9 25 LOAD_FAST 1 (c)
28 LOAD_CONST 2 ('02468')
31 COMPARE_OP 6 (in)
34 POP_JUMP_IF_FALSE 19
10 37 LOAD_FAST 0 (count)
40 LOAD_CONST 3 (1)
43 INPLACE_ADD
44 STORE_FAST 0 (count)
47 JUMP_ABSOLUTE 19
>> 50 POP_BLOCK
11 >> 51 LOAD_FAST 0 (count)
54 RETURN_VALUE
We can see that there's only one function call, that's to str() at the beginning:
9 LOAD_GLOBAL 0 (str)
...
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
Rest of it is highly optimized code, using jumps, stores, and inplace adding.
What comes to count_even_digits_spyr03_sum():
14 0 LOAD_GLOBAL 0 (sum)
3 LOAD_CONST 1 ( at 0x10dcc8c90, file "test.py", line 14>)
6 LOAD_CONST 2 ('count2..')
9 MAKE_FUNCTION 0
12 LOAD_GLOBAL 1 (str)
15 LOAD_GLOBAL 2 (n)
18 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
21 GET_ITER
22 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
25 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
28 RETURN_VALUE
While I can't perfectly explain the differences, we can clearly see that there are more function calls (probably sum() and in(?)), which make the code run much slower than executing the machine instructions directly.