Live data from Hacker News

How fast can we make interpreted Python?

phi-node.com

31–40 of 83 posts

Re: How fast can we make interpreted Python?

#31

There are a couple of things you want to do (some of which overlap with the article): 1) Use a register-based VM (with a sliding and growing register file) instead of a stack-based VM. In theory you can make a stack-based VM fast with lots of macroinstructions that fuse smaller operations together, but it isn't worth it. 2) Use inline caching for method calls, property accesses, and primitive operations that do type…

This is great, it's taken me months to learn all the things you just listed. Do you know of anywhere where this type of thing is discussed?

I mostly picked it up by working on interpreters and compilers, doing performance analysis on the generated code, trying to find all papers on the subject (some of them good, some of them really bad - you have to filter them yourself), and reading about what other implementations have been doing. It's also important to be able to run experiments quickly; you don't want to have to get every patch production-worthy before doing basic performance analysis.

Re: How fast can we make interpreted Python?

#32

There are a couple of things you want to do (some of which overlap with the article): 1) Use a register-based VM (with a sliding and growing register file) instead of a stack-based VM. In theory you can make a stack-based VM fast with lots of macroinstructions that fuse smaller operations together, but it isn't worth it. 2) Use inline caching for method calls, property accesses, and primitive operations that do type…

> 3) Pick your value encoding carefully. You almost always want fast immediate integers. On 64-bit platforms it is quite common these days to repurpose some of the NaN range in IEEE doubles for type tags to enable storing doubles in immediate values. That technique applies more to JavaScript, which uses doubles as the standard number type, than in Python, which has both integers and floats. Still a good idea to make…

Thanks for the correction, I wasn't aware that Python uses floats. I would guess that most new languages starting today would use doubles instead of floats.

Re: How fast can we make interpreted Python?

#33

While this is an undeniably cool project from the tech side, I think it's usually a better idea to rewrite bottlenecks of the kind that this helps with as a c extension. It's a fairly easy process (MUCH easier then in Java for example) and only a small amount of code needs to be in c itself but you can get huge performance increases without changing the Cython environment. I've always thought that was one of python/r…

I think you mean the "CPython environment"? "Cython" is something else.

Re: How fast can we make interpreted Python?

#35

The answer is very simple: 1) Know what ought to be done - do it and send the patches. 2) Need "speed" - write that part in C.)

2) Need "speed" - write that part in C.) That's not so easy. Interfacing Python and C code is also incredibly hard, and no one true way exists.

>That's not so easy. Interfacing Python and C code is also incredibly hard, and no one true way exists.

Can you elaborate on this. I've worked on python C extensions (just minor updates and fixes, I've never been the one to write significant chunks of it), and it seems like interfacing python with C is pretty straight forward.

Re: How fast can we make interpreted Python?

#36

Earlier quoted context omitted.

I don't buy that. I've had enough people relate Python's roots in the sysad tool belt and it's application in processing large data sets to believe that it's intended use case could be that limited.

And you shouldn't :) Python is used just about everywhere for just about everything (sometimes properly, sometimes poorly). While there are a lot of web sites that run Python, there are also countless other applications that use it that are unrelated to the web. See Scipy as an example. That said, the earlier poster mentioning that many people are using Python for IO bound processes is not too far a stretch. Why else…

I'm not denying that IO is important to a certain class of Python programs too; but I still can't see what leads to the conclusion that IO bound programs are the primary use case for Python. There are enough evented and async io libraries being built for just about every platform right now, that doesn't make IO the center of any of them.

Re: How fast can we make interpreted Python?

#37

The answer is very simple: 1) Know what ought to be done - do it and send the patches. 2) Need "speed" - write that part in C.)

2) Need "speed" - write that part in C.) That's not so easy. Interfacing Python and C code is also incredibly hard, and no one true way exists.

I've done it numerous times over the last several years and while it's probably not trivial, it's definitely not hard. If you're looking for a "one true way", it's Python's C API.

Re: How fast can we make interpreted Python?

#38

Earlier quoted context omitted.

And you shouldn't :) Python is used just about everywhere for just about everything (sometimes properly, sometimes poorly). While there are a lot of web sites that run Python, there are also countless other applications that use it that are unrelated to the web. See Scipy as an example. That said, the earlier poster mentioning that many people are using Python for IO bound processes is not too far a stretch. Why else…

I'm not denying that IO is important to a certain class of Python programs too; but I still can't see what leads to the conclusion that IO bound programs are the primary use case for Python. There are enough evented and async io libraries being built for just about every platform right now, that doesn't make IO the center of any of them.

And then there is the GIL. So if you want to squeeze more performance out of your CPU bound task. You need to use the multiprocess module, because Python threading does not work well for CPU bound tasks.

Re: How fast can we make interpreted Python?

#39
If you haven't already, LuaJIT's source code (and Mike Pall when asked) is a treasure trove of speedup ideas.

One idea that stood out to me (and which I first saw in LuaJIT, and as far as I know originated with Pall) is: when rewriting loop code, unroll at least 2 iterations of the loop. (The first executes and conditionally continues into the second; the second loops onto itself). So far, just extra work.

However, any kind of constant folding algorithm is now immediately elevated into a "code hoisting out of loop" algorithm at no extra cost - e.g., SSA form gets that kind of code motion.

I'm not sure Python can make much use of that, because it is nearly impossible to guarantee idempotence of operations - but in case you can somehow make that guarantee, that can be very significant for e.g. function name lookups.

A possible way to use that is to have the loop opcode have two branch targets: "namespaces modified" (which goes to the first iteration, which reloads values) and "namespaces unmodified" (which loops at the 2nd iteration, relying on the constant folding and not looking up in dicts again). This could make calls like "a.b.c.d.e.f" require 0 lookups in most iterations of most loops -- but would also require a global "namespace modified" flag.

Re: How fast can we make interpreted Python?

#40
post #15

It seems to me over the past ten years I've heard this story so many times: "Python sucks. Let's do the obvious thing that makes it faster." Then, a month or two later, "I did the obvious thing and it's sometimes faster but often slower, net no gain or possible loss." to which the response is obviously "No sale." I say this merely as an interesting observation. I've come to consider this a de facto counterargument to…

>It may be theoretically true, but in practice, as nice as Python may be to use, it has proved a very difficult language to speed up. I disagree with you. Python isn't much harder to speed up than Lua and in some ways it's better behaved than JavaScript. Still, both of those languages enjoy implementations significantly faster than CPython. Really, it's not the semantics of the language which hold back Python's perfo…

I think you underestimate the complexity of Python language.

Note that PyPy is not the only project that did that - remember psyco? There are reasons why after 3 years Armin said "I give up, let's do PyPy". It's not the "well behaved" part, this can be worked around, Python is simply more complex than Javascript or Lua and by complex I mean just bigger. All the extension modules that everyone naturally expects to be fast (even just the stdlib), descriptor protocol, crazy frame access semantics. That does make it very labour intensive to do the right thing. Look what happened to Unladen Swallow - they did not get anywhere really within a year. Several of PyPy optimizations that took forever to do are really new stuff, whether you do JIT by hand or generate it automatically.

Post reply on HN