On 11/10/2020 1:03 PM, Barry Scott wrote:


On 10 Nov 2020, at 14:45, David Kolovratník <da...@kolovratnik.net> wrote:

Dear all,

I would like to learn about constant folding optimisation in Python. It seems
to be implemented in Python/ast_opt.c. In order to get impression I used
python3 and dis module:

$ python3 -V
Python 3.7.3

I do not have answers to your questions, but I would suggest that you look at 
3.9
or even 3.10a2 to see if this is still the case.

Checking with 3.10...

Arithmetics expression is folded as expected:

dis.dis(compile('1 * 2', filename='<string>', mode='eval',
optimize=2))
  1           0 LOAD_CONST               0 (2)
              2 RETURN_VALUE

On the contrary, comparison remains for runtime:
dis.dis(compile('1 < 2', filename='<string>', mode='eval',
optimize=2))
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 COMPARE_OP               0 (<)
              6 RETURN_VALUE

Same.

In function fold_unaryop (though comparison is a binary operation) in
Python/ast_opt.c is remark: /* Fold not into comparison */

Use git blame to find out who and when made that remark.

Is there a reason why comparison (== != < > <= >=) is not folded? I would
expect it handled in fold_binop.

Besides comparison there are other expressions that might be optimized out
due to constant expression. Ternary operator with constant condition True
has IF optimized out (just some dead code remains):
dis.dis(compile('"a" if True else "b"', filename='<string>',
mode='eval', optimize=2))
  1           0 LOAD_CONST               1 ('a')
              2 RETURN_VALUE

Remains.

              4 LOAD_CONST               2 ('b')
              6 RETURN_VALUE

Gone.

On the contrary, the same ternary operator with constant condition False
still loads the constat and contains POP_JUMP_IF_FALSE:
dis.dis(compile('"a" if False else "b"', filename='<string>',
mode='eval', optimize=2))
  1           0 LOAD_CONST               0 (False)
              2 POP_JUMP_IF_FALSE        8
              4 LOAD_CONST               1 ('a')
              6 RETURN_VALUE
        >>    8 LOAD_CONST               2 ('b')
             10 RETURN_VALUE

Same. You could file issue for this, but one guess is that else clause might spill over to another line, and current decision is that for tracing, every line of code that naively should be executed is executed rather than optimized away. But I would first try to find the file that produces bytecode and then use git blame to find issue where the True else part was removed.

--
Terry Jan Reedy


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to