Quick question about CPython interpreter

David Lowry-Duda david at lowryduda.com
Mon Oct 17 11:43:59 EDT 2022


One can use the `dis` module and investigate the generated python 
bytecode. For me, I get

# file "dis1.py"
thing = 123
for i in range(10):
     if "hi" == str(thing):
         print("found")
         break

The bytecode is then

   1           0 LOAD_CONST               0 (123)
               2 STORE_NAME               0 (thing)

   2           4 LOAD_NAME                1 (range)
               6 LOAD_CONST               1 (10)
               8 CALL_FUNCTION            1
              10 GET_ITER
         >>   12 FOR_ITER                28 (to 42)
              14 STORE_NAME               2 (i)

   3          16 LOAD_CONST               2 ('hi')
              18 LOAD_NAME                3 (str)
              20 LOAD_NAME                0 (thing)
              22 CALL_FUNCTION            1
              24 COMPARE_OP               2 (==)
              26 POP_JUMP_IF_FALSE       12

   4          28 LOAD_NAME                4 (print)
              30 LOAD_CONST               3 ('found')
              32 CALL_FUNCTION            1
              34 POP_TOP

   5          36 POP_TOP
              38 JUMP_ABSOLUTE           42
              40 JUMP_ABSOLUTE           12
         >>   42 LOAD_CONST               4 (None)
              44 RETURN_VALUE

I note that line 22 calls the function str repeatedly, and no 
optimization is done here.

# file "dis2.py"
thing = 123
strthing = str(thing)
for i in range(10):
     if "hi" == strthing:
         print("found")
         break

This generates bytecode

   1           0 LOAD_CONST               0 (123)
               2 STORE_NAME               0 (thing)

   2           4 LOAD_NAME                1 (str)
               6 LOAD_NAME                0 (thing)
               8 CALL_FUNCTION            1
              10 STORE_NAME               2 (strthing)

   3          12 LOAD_NAME                3 (range)
              14 LOAD_CONST               1 (10)
              16 CALL_FUNCTION            1
              18 GET_ITER
         >>   20 FOR_ITER                24 (to 46)
              22 STORE_NAME               4 (i)

   4          24 LOAD_CONST               2 ('hi')
              26 LOAD_NAME                2 (strthing)
              28 COMPARE_OP               2 (==)
              30 POP_JUMP_IF_FALSE       20

   5          32 LOAD_NAME                5 (print)
              34 LOAD_CONST               3 ('found')
              36 CALL_FUNCTION            1
              38 POP_TOP

   6          40 POP_TOP
              42 JUMP_ABSOLUTE           46
              44 JUMP_ABSOLUTE           20
         >>   46 LOAD_CONST               4 (None)
              48 RETURN_VALUE

In short, it seems the cpython interpreter doesn't (currently) perform 
this sort of optimization.

- DLD


More information about the Python-list mailing list