Live data from Hacker News

Python 3.15's JIT is now back on track

fidget-spinner.github.io

321–330 of 330 posts

Re: Python 3.15's JIT is now back on track

#321

Earlier quoted context omitted.

Any decent JIT compiler (and HotSpot's is world class) will optimize this out. Likely this was done very early on in development, or was just to reduce bytecode size to promote inlining heuristics that use it

Untrue. Objects and attributes may be shared by threads so attribute accesses can't in general be localized.

It is true! If you explicitly synchronize between threads, sure, you can't optimize it in general, but if not, the compiler is well within its rights to cache the access.

Re: Python 3.15's JIT is now back on track

#322

Earlier quoted context omitted.

Pretty much my thoughts the other day... now that Codex does the writing, maybe I can finally switch to Go for the web backend stuff without being annoyed by some of its archaisms and gain significant execution performance, while still having a relatively easy to read language.

I have shifted as much as I can python to go when I don’t code. It’s just faster and the compiler catches more errors, win win,

Just tried this yesterday... great experience indeed. Go has archaisms and can be verbose but it's still very much readable and codex catches errors easily.

Re: Python 3.15's JIT is now back on track

#323
post #7

I'm been occasionally glancing at PR/issue tracker to keep up to date with things happening with the JIT, but I've never seen where the high level discussions were happening; the issues and PRs always jumped right to the gritty details. Is there anywhere a high-level introduction/example of how trace projection vs recording work and differ? Googling for the terms often returns CPython issue tracker as the first resul…

> I've never seen where the high level discussions were happening Thanks for your interest. This is something we could improve on. We were supposed to document the JIT better in 3.15, but right now we're crunching for the 3.15 release. I'll try to get to updating the docs soon if there's enough interest. PEP 744 does not document the new frontend. I wrote a somewhat high-level overview here in a previous blog post ht…

I saw your documentation PR, thank you!

I also did some reading and experiments, so quickly talking about things I've found out re: refcount elimination:

Previously given an expression `c = a + b`, the compiler generated a sequence of two LOADs (that increment the inputs' refcounts), then BINARY_OP that adds the inputs and decrements the refcounts afterwards (possibly deallocating the inputs).

But if the optimizer can prove that the inputs definitely will have existing references after the addition finishes (like when `a` and `b` are local variables, or if they are immortals like `a+5`), then the entire incref/decref pair could be ignored. So in the new version, the DECREFs part of the BINARY_OP was split into separate uops, which are then possibly transformed into POP_TOP_NOP by the optimizer.

And I'm assuming that although normally splitting an op this much would usually cost some performance (as the compiler can't optimize them as well anymore), in this case it's usually worth it as the optimization almost always succeeds, and even if it doesn't, the uops are still generated in several variants for various TOS cache (which is basically registers) states so they still often codegen into just 1-2 opcodes on x86.

One thing I don't entirely understand, but that's super specific from my experiment, not sure if it's a bug or special case: I looked at tier2 traces for `for i in lst: (-i) + (-i)`, where `i` is an object of custom int-like class with overloaded methods (to control which optimizations happen). When its __neg__ returns a number, then I see a nice sequence of

_POP_TOP_INT_r32, _r21, _r10.

But when __neg__ returns a new instance of the int-like class, then it emits

_SPILL_OR_RELOAD_r31, _POP_TOP_r10, _SPILL_OR_RELOAD_r01, _POP_TOP_r10, etc.

Is there some specific reason why the "basic" pop is not specialized for TOS cache? Is it because it's the same opcode as in tier1, and it's just not worth it as it's optimized into specialized uops most of the time; or is it that it can't be optimized the same way because of the decref possibly calling user code?

Re: Python 3.15's JIT is now back on track

#324

Earlier quoted context omitted.

> Python really needs to take the Typescript approach of "all valid Python4 is valid Python3 Great idea, but I'm not convinced that they learned anything from the Python 2 to 3 transition, so I wouldn't hold my breath. If you want a language system without contempt for backward compatibility, you're probably better off with Java/C++/JavaScript/etc. (though using JS libraries is like building on quicksand.) Bit of a s…

is that you, python core dev team? ;-)

I'll take that as a yes.

Re: Python 3.15's JIT is now back on track

#325

Earlier quoted context omitted.

> it is nuts that in an object method, there is a performance enhancement through caching a member value i don't understand what you think is nuts about this. it's an interpreted language and the word `self` is not special in any way (it's just convention - you can call the first param to a method anything you want). so there's no way for the interpreter/compiler/runtime to know you're accessing a field of the class…

If you dig into JS engine implementations they deal with a lot of the same sorts of things. Simple objects with straightforward properties are tagged such that they skip the dynamic machinery with fallback paths to deal with dynamism when it is necessary. A common approach is hidden classes that work much like classes in other languages. Reading a simple int property just reads bytes at an offset from the object poin…

https://wiki.python.org/moin/UsingSlots

Re: Python 3.15's JIT is now back on track

#326

Earlier quoted context omitted.

Untrue. Objects and attributes may be shared by threads so attribute accesses can't in general be localized.

It is true! If you explicitly synchronize between threads, sure, you can't optimize it in general, but if not, the compiler is well within its rights to cache the access.

Sure, if the compiler can prove that the objects are thread-local. But that's not the general case.

Re: Python 3.15's JIT is now back on track

#327

Earlier quoted context omitted.

It's very Pythonic to expose e.g. state via the existence of attributes. This also makes it possible to dynamically expose foreign language interfaces. You can really craft the interface you like, because the interface exposal is also normal code that returns strings and objects. You are right that it is not needed often, but there is often somewhere a part in the library stack that does exactly this, to expose a nic…

This is just an analogy but in Swift String is such a commonly used hot path the type is designed to accommodate different backing representations in a performant way. The type has bits in its layout that indicate the backing storage. eg a constant string is just a pointer to the bytes in the binary and unless the String escapes or mutates incurs no heap allocation at all - it is just a stack allocation and a pointer…

It already has a fast path, from (I think) 3.11. If you run `object.x` repeatedly on the same type of object enough times, the interpreter will swap out the LOAD_ATTR opcode to `LOAD_ATTR_INSTANCE_VALUE` or `LOAD_ATTR_SLOT`, which only makes sure that the type is the same as before and loads the value from a specified offset, without doing a full lookup.

Re: Python 3.15's JIT is now back on track

#328
post #117

Earlier quoted context omitted.

I cannot believe people are still acting like Python 2->3 was a huge fuck-up and an enormous missed opportunity. When in reality Python is by most measures the most popular language and became so AFTER that switch. Since the switch we have seen enormous companies being built from scratch. There is no reason for anyone to be complaining about it being too hard to upgrade in 2026

> Python is by most measures the most popular language and became so AFTER that switch The switch had nothing to do with Python's rise in popularity though, it was because of NumPy and later PyTorch being adopted by data scientist and later machine learning tasks that themselves became very popular. Python's popularity rose alongside those. > There is no reason for anyone to be complaining about it being too hard to…

> The switch had nothing to do with Python's rise in popularity though

You don't realise it but you have actually made my point. People are acting like was a suicidal, harmful move that fucked over Python and ... it didn't matter because Python went on to become insanely popular. Particularly hilarious is that some people have tried to argue that Perl somehow did it better.

In the end your Python 2 project was either worth porting and you did it, or it wasn't worth it and you didn't. Python has gone on to be an undeniable success and it is nearly unthinkable that anyone would use Python 2 for anything. It is absolutely fucking insane for people to still be whining about this in this day and age

Re: Python 3.15's JIT is now back on track

#329
post #152
post #117

Earlier quoted context omitted.

I cannot believe people are still acting like Python 2->3 was a huge fuck-up and an enormous missed opportunity. When in reality Python is by most measures the most popular language and became so AFTER that switch. Since the switch we have seen enormous companies being built from scratch. There is no reason for anyone to be complaining about it being too hard to upgrade in 2026

Those are unrelated.

I am saying that 2-to-3 has not affected Python becoming the most popular programming language whatsoever. So I guess in a way you're right to say the two things are "unrelated" but you're not exactly disagreeing with me - it'd be like if I said "water is a liquid" and you said "nuh-uh, it's wet"

Re: Python 3.15's JIT is now back on track

#330
post #7

I'm been occasionally glancing at PR/issue tracker to keep up to date with things happening with the JIT, but I've never seen where the high level discussions were happening; the issues and PRs always jumped right to the gritty details. Is there anywhere a high-level introduction/example of how trace projection vs recording work and differ? Googling for the terms often returns CPython issue tracker as the first resul…

Occasionally Core.py will do some updates, higher level stuff:

https://open.spotify.com/show/1PGRfdrLEwgXjQbPBNk1pW

pablo and Łukasz

Post reply on HN