Live data from Hacker News

Python performance myths and fairy tales

lwn.net

91–100 of 221 posts

Re: Python performance myths and fairy tales

#91
post #80

Earlier quoted context omitted.

In Smalltalk, p x * 2 has that flow that as well, and even worse, lets assume the value returned by p x message selector, does not understand the * message, thus it will break into the debugger, then the developer will add the * message to the object via the code browser, hit save, and exit the debugger with redo, thus ending the execution with success. Somehow Smalltalk JIT compilers handle it without major issues.

Smalltalk JITs make p x * 2 fast by speculating on types and inserting guards, not by skipping semantics. Python JITs do the same (e.g. PyPy), but Python’s dynamic features (like __getattribute__, unbounded ints, C-API hooks) make that harder and costlier to optimize away. You get real speed in Python by narrowing the semantics (e.g. via NumPy, Numba, or Cython) not by hoping the compiler outsmarts the language.

People keep forgetting about image based semantics development, debugger, meta-classes, messages like becomes:,...

There is to say everything dynamic that can be used as Python excuse, Smalltalk and Self, have it, and double up.

Re: Python performance myths and fairy tales

#92
post #47

Python as a language will likely never have a "fast" implementation and still be Python. It is way too dynamic to be predictable from the code alone or even an execution stream in a way that allows you to simplify the actual code that will be executed at runtime either through AOC or JIT. The language is itself is also quite large in terms of syntax and built-in capability at this point which makes new feature-conple…

Pypy is 10x faster and is compatible with most cpython code. IMHO it was a big mistake not to adopt JIT during the 2-to-3 transition.

That “most” is doing a big lift there. At some point you might consider that you’re actually programming in the language of Pypy and not pure Python. It’s effectively a dialect of the language like Turbo Pascal vs ISO Pascal or RPerl instead of Perl.

Re: Python performance myths and fairy tales

#93

So we are paying 99% of the performance just for the 1% of cases where it's nice to code in. Why do people think it's a good trade-off?

I don't think anyone aware of this thinks it's a good tradeoff.

The more interesting question is why the tradeoff was made in the first place.

The answer is, it's relatively easy for us to see and understand the impact of these design decisions because we've been able to see their outcomes over the last 20+ years of Python. Hindsight is 20/20.

Remember that Python was released in 1991, before even Java. What we knew about programming back then vs what we know now is very different.

Oh and also, these tradeoffs are very hard to make in general. A design decision that you may think is irrelevant at the time may in fact end up being crucial to performance later on, but by that point the design is set in stone due to backwards compatibility.

Re: Python performance myths and fairy tales

#94
post #87

The most interesting part of this article is the link to SPy. Attempts to find a subset of python that could be made performant.

Honestly that seems Sisyphean to me. The market doesn't want a "performant subset". The market is very well served by performant languages. The market wants Python's expressivity. The market wants duck typing and runtime-inspectable type hierarchies and mutable syntax and decorators. It loves it. It's why Python is successful. My feeling is that numba has exactly the right tactic here. Don't try to subset python from…

> The market wants duck typing and runtime-inspectable type hierarchies and mutable syntax and decorators. It loves it.

These features have one thing in common: they're only useful for prototype-quality throwaway code, if at all. Once your needs shift to an increased focus on production use and maintainability, they become serious warts. It's not just about performance (though it's obviously a factor too), there's real reasons why most languages don't do this.

Re: Python performance myths and fairy tales

#96

I don't know Python so well as to propose any meaningful contribution, but it seems to me that most issues would be mitigated by a sort of "final" statement or qualifier, that prohibits any further changes to the underlying data structure, thus enabling all the nice optimizations, tricks and shortcuts that compilers and interpreters can't afford when data is allowed to change shape under their feet.

I assume people dislike those kinds of solutions because the extreme dynamism is used pretty rarely in a lot of meat and potatoes python scripst. So a lot of “regular” python scripts would have to just plaster “final” everywhere to make it as fast as it can be.

At that point youd maybe want to have some sort of broader way to signify which parts of your script are dynamic. But then, youd have a language that can be dynamic even in how dynamic it is…

Re: Python performance myths and fairy tales

#97
post #86
post #16

I think an important bit of context here is that computers are very, very good at speculative happy-path execution. The examples in the article seem gloomy: how could a JIT possibly do all the checks to make sure the arguments aren’t funky before adding them together, in a way that’s meaningfully better than just running the interpreter? But in practice, a JIT can create code that does these checks, and modern proces…

> but v8 has made common use cases extremely fast. I’m excited for the future of Python. Isn't v8 still entirely single threaded with limited message passing? Python just went through a lot of work to make multithreaded code faster, it would be disappointing if it had to scrap threading entirely and fall back to multiprocessing on shared memory in order to match v8.

JS is single-threaded. Python isn't.

Re: Python performance myths and fairy tales

#98
post #80

Earlier quoted context omitted.

A “sufficiently smart compiler” can’t legally skip Python’s semantics. In Python, p.x * 2 means dynamic lookup, possible descriptors, big-int overflow checks, etc. A compiler can drop that only if it proves they don’t matter or speculates and adds guards—which is still overhead. That’s why Python is slower on scalar hot loops: not because it’s interpreted, but because its dynamic contract must be honored.

In Smalltalk, p x * 2 has that flow that as well, and even worse, lets assume the value returned by p x message selector, does not understand the * message, thus it will break into the debugger, then the developer will add the * message to the object via the code browser, hit save, and exit the debugger with redo, thus ending the execution with success. Somehow Smalltalk JIT compilers handle it without major issues.

edit and continue is available on lots of JIT-runtime languages

Re: Python performance myths and fairy tales

#99
post #82

Earlier quoted context omitted.

Has it ever crossed your mind that they just like Python?

And slow code, yes it has cross my mind. Usually they also call Python to libraries that are 95% C code.

The hypocrisy gets even worse: the C code then gets compiled to assembly!

Re: Python performance myths and fairy tales

#100
post #92
post #47

Earlier quoted context omitted.

Pypy is 10x faster and is compatible with most cpython code. IMHO it was a big mistake not to adopt JIT during the 2-to-3 transition.

That “most” is doing a big lift there. At some point you might consider that you’re actually programming in the language of Pypy and not pure Python. It’s effectively a dialect of the language like Turbo Pascal vs ISO Pascal or RPerl instead of Perl.

Most is more CPython code than python 3 was compatible with. But the port of the broken code was likely much easier than if it had moved to a JIT at the same time too.
Post reply on HN