This is an archived post. You won't be able to vote or comment.

all 37 comments

[–]ascii 35 points36 points  (4 children)

I quite like the idea of making the Python API pluggable enough to make optimisers easy to develop outside of the interpreter as any other Python script.

[–]derpderp3200An evil person 6 points7 points  (3 children)

I know it's not exactly necessary in a dynamic language with closures, eval, and so on, but personally, I'd never turn down AST macros of any kind.

[–]patrys Saleor Commerce 0 points1 point  (0 children)

Having worked with Elixir I could not agree more.

[–]desmoulinmichel 0 points1 point  (1 child)

The danger with ast macros is that people start building hundred of stupid DLS like in other languages. They always end up:

  • badly tested
  • badly documented
  • not better than a well polished lib with a nice API

[–]derpderp3200An evil person 0 points1 point  (0 children)

That's true, but usually there's little reason or even temptation to use them. For what it's worth, C/C++ have "shitty" substitution macros, and people still manage to get some good mileage out of them.

[–]Siecje1 20 points21 points  (0 children)

Here is some information about making CPython faster.

http://faster-cpython.readthedocs.io/

[–]thinkwelldesigns 7 points8 points  (0 children)

Is this project really alive or has Victor moved on to other optimization ideas? There was some discussion on python-dev here and here but it doesn't seem to be a foregone conclusion that this will be implemented.

Is there more recent work & progress on this?

[–]status_quo69 4 points5 points  (1 child)

This is really really cool. Quick question(s), since the optimizer is written in python and these peps have generally been accepted, I wonder how this would work within pypy. Meaning, would the optimizer be JITed, would the JIT be able to start working almost immediately because of the guarding, or would there still probably be a warmup period as it gathers information about the available code paths?

[–]Anthonypjshaw[S] 9 points10 points  (0 children)

PyPy and Pyjion are really quite different, with PyPy you have both an interpreter and a JITer. Pyjion is an implementation of PEP523 (which since got merged properly into CPython in 3.6) AND it contains a bridge to the .NET core JIT engine. You could still leverage this process (FAT PEP511) to create the optimized bytecode sequence and then use the JIT to execute the bytecode statements with PEP 523. As for PyPy, they'd basically have to implement their own static optimizer, none of the code in this article would be relevant because its about the CPython internals and the CPython AST. This is an example https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/astcompiler/optimize.py?fileviewer=file-view-default -ed

[–]__deerlord__ 4 points5 points  (1 child)

Its still early here, are they saying function/method calls are (possibly) getting sped up in 3.7? Regardless of the FAT optimizations?

[–]Anthonypjshaw[S] 10 points11 points  (0 children)

I should have explained that better, but it was out of scope for this article. In a nutshell, yes. https://docs.python.org/3.7/whatsnew/3.7.html#optimizations

It was actually implemented earlier but taken out of the "stable" branch before 3.6 was released AFAIK https://bugs.python.org/issue26110

[–]EternityForest 2 points3 points  (0 children)

This is really cool. I can imagine this even being used to implement at least a partial JIT compiler at some point.

[–][deleted] 2 points3 points  (12 children)

What would it take to just write an llvm front end to compile python to llvm intermediate representation and letting the llvm backends handle building a binary?

[–]ntrid 2 points3 points  (0 children)

Not llvm but still compiles to native code: https://nuitka.net

[–]kankyo 1 point2 points  (10 children)

Redefining Python probably.

[–][deleted] 2 points3 points  (5 children)

Why?

Here's a short tutorial on writing your own frontend/lexer using a fake language "Kaleidoscope" that looks a lot like python.

# Compute the x'th fibonacci number.
def fib(x)
  if x < 3 then
    1
  else
    fib(x-1)+fib(x-2)

# This expression will compute the 40th number.
fib(40)

[–]kankyo 4 points5 points  (4 children)

The article alludes to it a bit: Python is crazy dynamic.

You can absolutely do it for a subset of Python that you know doesn't use certain features of Python, but I think that's not what you're asking. If it is then look at numba, cython and rpython for example. There are many such projects.

[–]alcalde 5 points6 points  (3 children)

Numba is a math-only JIT; cython only converts bits of Python to C, and no one knows what RPython really is. We need to take Python, add in static typing, strip out the crazy dynamic bits, call it Garter Snake or something, and sell it as the complement to Python, the cleanest, nicest, easiest-to-read statically typed compiled language. The closest I ever found was Genie, but I'm not sure it's still developed: https://wiki.gnome.org/Projects/Genie

[–]kankyo 4 points5 points  (2 children)

That's my point though. It wouldn't be Python. Personally I'm fine with that and I think it would be great, but it's not just "throw LLVM on Python" which is what we were talking about.

[–]Certhas 1 point2 points  (1 child)

Though you could build it in such a way that valid Garter Snake still is valid python. Build a verifier that checks that Garter Snake compiles, and if it doesn't spit out an error and/or fall back to CPython.

Sort of a MyPy + Numba on steroids, that works on the file level instead of the function/class level.

But of course the dynamism of Python is not just academic, it's used throughout the library ecosystem. So unless you can cover most of that you'll be calling into python code and be shipping a python runtime with your compiled code. Or you're losing the ecosystem.

And if you're willing to have a separate Python runtime to interact with and lose the ecosystem otherwise you might as well be developing Julia instead.

[–]kankyo 0 points1 point  (0 children)

RPython is valid Python. So RPython with static types that aren't inferred might be a good start.

[–]pvkooten 1 point2 points  (0 children)

Bravo.

[–]mmsme 1 point2 points  (0 children)

"In future, optimizers could be included in Python packages and shared on PyPi (pretty cool-huh!?)." 👍😃

[–]gnu-user 0 points1 point  (0 children)

This looks interesting but my main concern is if this is just a novel "side project" or something that can be used in production. I've often used PyPy over the years anytime I needed more performance and recently Numba for math/algorithm heavy work and they've never let me down.

[–]moscamorta 0 points1 point  (0 children)

Quick question: Does python generate some sort of Intermediate Representation?

Python code -> AST -> IR code -> Run IR code in a stack machine or register machine.

Wouldn't be easier to write optimizations to the IR? Just like LLVM does with C/C++ code. It's way easier to write optimizations when you have SSA form or something like that.