[Python-ideas] PEP 511: API for code transformers

Yury Selivanov yselivanov.ml at gmail.com
Fri Jan 15 15:39:53 EST 2016


Hi Victor,

On 2016-01-15 11:10 AM, Victor Stinner wrote:
> Hi,
>
> This PEP 511 is part of a serie of 3 PEP (509, 510, 511) adding an API
> to implement a static Python optimizer specializing functions with
> guards.

All your PEPs are very interesting, thanks for your hard work!
I'm very happy to see that we're trying to make CPython faster.

There are some comments below:

>
> If the PEP is accepted, it will solve a long list of issues, some
> issues are old, like #1346238 which is 11 years old ;-) I found 12
> issues:
>
> * http://bugs.python.org/issue1346238
> * http://bugs.python.org/issue2181
> * http://bugs.python.org/issue2499
> * http://bugs.python.org/issue2506
> * http://bugs.python.org/issue4264
> * http://bugs.python.org/issue7682
> * http://bugs.python.org/issue10399
> * http://bugs.python.org/issue11549
> * http://bugs.python.org/issue17068
> * http://bugs.python.org/issue17430
> * http://bugs.python.org/issue17515
> * http://bugs.python.org/issue26107

It's important to say that all of those issues (except 2506)
are not bugs, but proposals to implement some nano- and
micro- optimizations.

Issue 2506 is about having an option to disable the peephole
optimizer, which is a very narrow subset of what PEP 511
proposes to add.

[..]
> Usage 2: Preprocessor
> ---------------------
>
> A preprocessor can be easily implemented with an AST transformer. A
> preprocessor has various and different usages.
>
> Some examples:
>
> * Remove debug code like assertions and logs to make the code faster to
>    run it for production.
> * `Tail-call Optimization <https://en.wikipedia.org/wiki/Tail_call>`_
> * Add profiling code
> * `Lazy evaluation <https://en.wikipedia.org/wiki/Lazy_evaluation>`_:
>    see `lazy_python <https://github.com/llllllllll/lazy_python>`_
>    (bytecode transformer) and `lazy macro of MacroPy
>    <https://github.com/lihaoyi/macropy#lazy>`_ (AST transformer)
> * Change dictionary literals into collection.OrderedDict instances
> * Declare constants: see `@asconstants of codetransformer
>    <https://pypi.python.org/pypi/codetransformer>`_
> * Domain Specific Language (DSL) like SQL queries. The
>    Python language itself doesn't need to be modified. Previous attempts
>    to implement DSL for SQL like `PEP 335 - Overloadable Boolean
>    Operators <https://www.python.org/dev/peps/pep-0335/>`_ was rejected.
> * Pattern Matching of functional languages
> * String Interpolation, but `PEP 498 -- Literal String Interpolation
>    <https://www.python.org/dev/peps/pep-0498/>`_ was merged into Python
>    3.6.
[..]

I think that most of those examples are rather weak.  Things like
tail-call optimizations, constants declarations, pattern matching,
case classes (from MacroPy) are nice concepts, but they should be
either directly implemented in Python language or not used at all
(IMHO).

Things like auto-changing dictionary literals to OrderedDict
objects or in-Python DSLs will only help in creating hard to
maintain code base.  I say this because I have a first-hand
experience with decorators that patch opcodes, and import
hooks that rewrite AST.  When you get back to your code years
after it was written, you usually regret about doing those things.

All in all, I think that adding a blessed API for preprocessors
shouldn't be a focus of this PEP.  MacroPy works right now
with importlib, and I think it's a good solution for it.

I propose to only expose new APIs on the C level,
and explicitly mark them as provisional and experimental.
It should be clear, that those APIs are only for
*writing optimizers*, and nothing else.

[off-topic] I do think that having a macro system similar to
Rust might be a good idea.  However, macro in Rust have explicit
and distinct syntax, they have the necessary level of
documentation and tooling.  But this is a separate matter
deserving its own PEP ;)

[..]
> Usage 4: Write new bytecode optimizers in Python
> ------------------------------------------------
>
> Python 3.6 optimizes the code using a peephole optimizer. By
> definition, a peephole optimizer has a narrow view of the code and so
> can only implement basic optimizations. The optimizer rewrites the
> bytecode. It is difficult to enhance it, because it written in C.
>
> With this PEP, it becomes possible to implement a new bytecode optimizer
> in pure Python and experiment new optimizations.
>
> Some optimizations are easier to implement on the AST like constant
> folding, but optimizations on the bytecode are still useful. For
> example, when the AST is compiled to bytecode, useless jumps can be
> emited because the compiler is naive and does not try to optimize
> anything.
[..]

Would it be possible to (or does it make any sense):

1. Add new APIs for AST transformers (only exposed on the C
level!)

2. Remove the peephole optimizer.

3. Re-implement peephole optimizer using new APIs in CPython
(peephole does some very basic optimizations).

4. Implement other basic optimizations (like limited constant
folding) in CPython.

5. Leave the door open for you and other people to add more
AST optimizers (so that FAT isn't locked to CPython's slow
release cycle)?


I also want to say this: I'm -1 on implementing all three PEPs
until we see that FAT is able to give us at least 10% performance
improvement on micro-benchmarks.  We still have several months
before 3.6beta to see if that's possible.


Thanks,
Yury


More information about the Python-ideas mailing list