Quick question about CPython interpreter

MRAB python at mrabarnett.plus.com
Mon Oct 17 12:25:34 EDT 2022


On 2022-10-17 16:43, David Lowry-Duda wrote:
> 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.
> 
It can't optimise that because, say, 'print' could've been bound to a 
function that rebinds 'str'.


More information about the Python-list mailing list