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
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to