Live data from Hacker News

How fast can we make interpreted Python?

phi-node.com

21–30 of 83 posts

Re: How fast can we make interpreted Python?

#21

Can we make function calls cheaper? From my observations in pretty much any unoptimized Python (CPython interpreted) code function calls is nearly always a bottleneck. And speed is directly bound by the number of function calls being performed, not by ponderous data structures.

The ponderousness of these data structures isn't just about memory consumption or having to use boxed numbers. As far as performance goes, PyObjects infect everything in the interpreter. For example, when you're calling a Python function, after a long run-around in ceval, PyObject_Call, the function object's function_call method, you'll finally get back to ceval which creates a frame via a lengthy call to PyFrame_New. The whole process is a mess of allocating, deconstructing, increfing, decrefing, and tag-checking.

Re: How fast can we make interpreted Python?

#22
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…

There is some truth here; even the militantly dynamic Common lisp has a blisteringly fast implementation (SBCL).

Re: How fast can we make interpreted Python?

#24

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 sure that both native integers and native floats end up as unboxed native types in registers, though.

Re: How fast can we make interpreted Python?

#26

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…

>Rearrange your instruction bodies based on execution / transition frequencies to improve instruction cache performance. Do you mean...group all the frequent operations together so they overlap on cache lines? It's hard to tell how much this would help, have you tried it?

Looks like he's contributed significantly to the Webkit javascript interpreter: https://www.webkit.org/blog/196/cameron-zwarich-is-a-webkit-...

Re: How fast can we make interpreted Python?

#27

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?

Re: How fast can we make interpreted Python?

#28

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.

Re: How fast can we make interpreted Python?

#29

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?

Language implementation sometimes gets discussed up on lambda-the-ultimate . Also, searching for anything and everything Mike Pall has written about VM design is probably worthwhile. Mozilla developers also have some pretty interesting blog posts about TraceMonkey, IonMonkey and all the other monkeys.

Re: How fast can we make interpreted Python?

#30

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…

>Rearrange your instruction bodies based on execution / transition frequencies to improve instruction cache performance. Do you mean...group all the frequent operations together so they overlap on cache lines? It's hard to tell how much this would help, have you tried it?

When I was working on WebKit we would rearrange instruction bodies to influence the generated code based on opcode statistics, but back then the interpreter was using computed goto, so there wasn't quite a direct connection between the placement of the input code and the generated code. It's unlikely that any two instruction implementations will overlap on cache lines, since they are all typically larger than a cache line, but more temporal coherency throughout code execution will improve performance, especially on CPUs with smaller caches.

You can do it automatically by gathering statistics on frequent instruction pairs. In practice greedy algorithms for code scheduling work fairly well, assuming you have meaningful statistics.

Post reply on HN