[HN Gopher] Python 3.15's JIT is now back on track
___________________________________________________________________
Python 3.15's JIT is now back on track
Author : guidoiaquinti
Score : 196 points
Date : 2026-03-17 18:37 UTC (4 hours ago)
(HTM) web link (fidget-spinner.github.io)
(TXT) w3m dump (fidget-spinner.github.io)
| oystersareyum wrote:
| > We don't have proper free-threading support yet, but we're
| aiming for that in 3.15/3.16. The JIT is now back on track.
|
| I recently read an interview about implementing free-threading
| and getting modifications through the ecosystem to really enable
| it: https://alexalejandre.com/programming/interview-with-
| ngoldba...
|
| The guy said he hopes the free-threaded build'll be the only one
| in "3.16 or 3.17", I wonder if that should apply to the JIT too
| or how the JIT and interpreter interact.
| zarzavat wrote:
| I continue to believe that free-threading hurts performance
| more than it helps and Python should abandon it.
|
| Having to have thread safe code all over the place just for the
| 1% of users who need to have multi-threading in Python and
| can't use subinterpreters for some reason is nuts.
| kzrdude wrote:
| I don't want to go too heavy on the negatives, but what's
| nuts is Python going for trust-the-programmer style
| multithreading. The risk is that extension modules could
| cause a lot of crashes.
| pansa2 wrote:
| Maybe they could have two versions of the interpreter, one
| that's thread-safe and one that's optimised for single-
| threading?
|
| Microsoft used to do this for their C runtime library.
| ekjhgkejhgk wrote:
| Doesn't PyPy already have a jit compiler? Why aren't we using
| that?
| olivia-banks wrote:
| As far as I know, PyPy doesn't support all CPython extensions,
| so pure Python code will probably (very likely) run fine but
| for other things most bets are off. I believe PyPy also only
| supports up to 3.11?
| JoshTriplett wrote:
| Because PyPy seems to be defunct. It hasn't updated for quite a
| while.
|
| See https://github.com/numpy/numpy/issues/30416 for example.
| It's not being updated for compatibility with new versions of
| Python.
| LtWorf wrote:
| last release 4 days ago.
|
| Can you please not post "facts" you just invented yourself?
| Waterluvian wrote:
| It supports at best Python 3.11 code, right?
|
| So it's not unmaintained, no. But the project is currently
| under resourced to keep up with the latest Python spec.
| LtWorf wrote:
| That is not the same thing at all, and not what he said.
| JoshTriplett wrote:
| It is exactly what I'm referring to. I didn't say there
| aren't still people around. But they're far enough behind
| CPython that folks like NumPy are dropping support.
| Unless they get a substantial injection of new people and
| new energy, they're likely to continue falling behind.
| mkl wrote:
| PyPy's devs disagree:
| https://news.ycombinator.com/item?id=47293415
| contravariant wrote:
| Why shouldn't the reference implementation get JIT? Just
| because some other implementations already have it is no reason
| not to. That'd be like skipping list comprehensions because
| they already exist in CPython.
| 3laspa wrote:
| Because the same people who made a big deal about supporting
| PyPy and PEP 399 when it was fashionable to do so are now told
| by their corporations that PyPy does not matter. CPython only
| moves with what is currently fashionable, employer mandated and
| profitable.
| cpburns2009 wrote:
| PyPy is limited to maintenance mode due to a lack of
| funding/contributors. In the past, I think a few contributors
| or funding is what helped push "minor" PyPy versions. It's too
| bad PyPy couldn't take the federal funding the PSF threw away.
| hrmtst93837 wrote:
| PyPy isn't CPython.
|
| A lot of Python code still leans on CPython internals, C
| extensions, debuggers, or odd platform behavior, so PyPy works
| until some dependency or tool turns that gap into a support
| problem.
|
| The JIT helps on hot loops, but for mixed workloads the warmup
| cost and compatibility tax are enough to keep most teams on the
| interpreter their deps target first.
| adrian17 wrote:
| 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 result, and repo's jit.md is
| relatively barebones and rarely updated :(
|
| Similarly, I don't entirely understand refcount elimination; I've
| seen the codegen difference, but since the codegen happens at
| build time, does this mean each opcode is possibly split into two
| (or more?) stencils, with and without removed increfs/decrefs?
| With so many opcodes and their specialized variants, how many
| stencils are there now?
| flakes wrote:
| You'll probably want to look to the PEPs. Havent dug into this
| topic myself but looks related
| https://peps.python.org/pep-0744/
| adrian17 wrote:
| I think CPython already had tier2 and some tracing
| infrastructure when the copy-and-patch JIT backend was added;
| it's the "JIT frontend" that's more obscure to me.
| sheepscreek wrote:
| I love playing with compilers for fun, so maybe I can shed some
| light. I'll explain it in a simplified way for everyone's
| benefit (going to ignore the stack):
|
| When an object is passed between functions in Python, it
| doesn't get copied. Instead, a reference to the object's memory
| address is sent. This reference acts as a pointer to the
| object's data. Think of it like a sticky note with the object's
| memory address written on it. Now, imagine throwing away one
| sticky note every time a function that used a reference
| returns.
|
| When an object has zero references, it can be freed from memory
| and reused. Ensuring the number of references, or the
| "reference count" is always accurate is therefore a big deal.
| It is often the source of memory leaks, but I wouldn't
| attribute it to a speed up (only if it replaces GC, then yes).
| yuliyp wrote:
| what at all does this comment have to do with what it's
| replying to?
| saikia81 wrote:
| have you read the dev mailing list? There the developers of
| python discuss lots.
| pansa2 wrote:
| There isn't a dev mailing list any more, is there? Do you
| mean the Discord forum?
| ecshafer wrote:
| What is wrong with the Python code base that makes this so much
| harder to implement than seemingly all other code bases? Ruby,
| PHP, JS. They all seemed to add JITs in significantly less time.
| A Python JIT has been asked for for like 2 decades at this point.
| stmw wrote:
| Some languages are much harder to compile well to machine code.
| Some big factors (for any languages) are things like: lack of
| static types and high "type uncertainty", other dynamic
| language features, established inefficient extension interfaces
| that have to be maintained, unusual threading models...
| RussianCow wrote:
| That makes sense if you're comparing with Java or C#, but not
| Ruby, which is _way_ more dynamic than Python.
|
| The more likely reason is that there simply hasn't been that
| big a push for it. Ruby was dog slow before the JIT and Rails
| was very popular, so there was a lot of demand and room for
| improvement. PHP was the primary language used by Facebook
| for a long time, and they had deep pockets. JS powers the
| web, so there's a huge incentive for companies like Google to
| make it faster. Python never really had that same level of
| investment, at least from a performance standpoint.
|
| To your point, though, the C API has made certain types of
| optimizations extremely difficult, as the PyPy team has
| figured out.
| vlovich123 wrote:
| Google, Dropbox, and Microsoft from what I can recall all
| tried to make Python fast so I don't buy the "hasn't seen a
| huge amount of investment". For a long time Guido was
| opposed to any changes and that ossified the ecosystem.
|
| But the main problem was actually that pypy was never
| adopted as "the JIT" mechanism. That would have made a huge
| difference a long time ago and made sure they evolved in
| lock step.
| int_19h wrote:
| Microsoft is the one the TFA refers to cryptically when
| it says "the Faster CPython team lost its main sponsor in
| 2025".
|
| AFAIK it was not driven by anything on the tech side. It
| was simply unlucky timing, the project getting in the
| middle of Microsoft's heavy handed push to cut
| everything. So much so that the people who were hired by
| MS to work on this found out they were laid off in a
| middle of a conference where they were giving talks on
| it.
| flykespice wrote:
| > Python never really had that same level of investment, at
| least from a performance standpoint.
|
| Or lack of incentive?
|
| Alot of big python projects that does machine learning and
| data processing offloads the heavy data processing from
| pure python code to libraries like numpy and pandas that
| take advantage of C api binding to do native execution.
| simonask wrote:
| The simplest JIT just generates the machine code instructions
| that the interpreter loop would execute anyway. It's not an
| extremely difficult thing, but it also doesn't give you much
| benefit.
|
| A worthwhile JIT is a fully optimizing compiler, and that is
| the hard part. Language semantics are much less important -
| dynamic languages aren't particularly harder here, but the
| performance roof is obviously just much lower.
| wat10000 wrote:
| PHP and JS had huge tech companies pouring resources into
| making them fast.
| brokencode wrote:
| Are you forgetting about PyPy, which has existed for almost 2
| decades at this point?
| RussianCow wrote:
| That's a completely separate codebase that purposefully
| breaks backwards compatibility in specific areas to achieve
| their goals. That's not the same as having a first-class JIT
| in CPython, the actual Python implementation that ~everyone
| uses.
| brokencode wrote:
| Definitely agree that it's better to have JIT in the
| mainline Python, but it's not like there weren't options if
| you needed higher performance before.
|
| Including simply implementing the slow parts in C, such as
| the high performance machine learning ecosystem that exists
| in Python.
| 0cf8612b2e1e wrote:
| The Python C api leaks its guts. Too much of the internal
| representation was made available for extensions and now
| basically any change would be guaranteed to break backwards
| compatibility with something.
| patmorgan23 wrote:
| Ooo this makes sense it's like if the Linux had don't break
| users space AND a whole bunch of other purely internal APIs
| you also can't refactor.
| echelon wrote:
| It's a shame that Python 2->3 transition was so painful,
| because Python could use a few more clean breaks with the
| past.
|
| This would be a potential case for a new major version
| number.
| froobius wrote:
| On the other hand, taking backwards compatibility so
| seriously is a big part of the massive success of Python
| IshKebab wrote:
| Python does not take backwards compatibility very
| seriously at all. Take a look at all the deprecated APIs.
|
| I would say it's _probably_ worth it to clean up all the
| junk that Python has accumulated... But it 's definitely
| not very high up the list of languages in terms of
| backwards compatibility. In fact I'm struggling to think
| of other languages that are worse. Typescript probably?
| Certainly Go, C++ and Rust are significantly better.
| pansa2 wrote:
| >> Python 2->3 transition
|
| > taking backwards compatibility so seriously
|
| Python's backward compatibility story still isn't great
| compared to things like the Go 1.x compatibility promise,
| and languages with formal specs like JS and C.
|
| The Python devs still make breaking changes, they've just
| learned not to update the major version number when they
| do so.
| BarryMilo wrote:
| Indeed, Python's version format is semver but it's just
| aesthetics, they remove stuff in most (every?) minor
| version. Just yesterday I wasted hours trying to figure
| out a bug before realizing my colleague hadn't read the
| patch notes.
| __mharrison__ wrote:
| I would argue that the libraries, and specifically NumPy,
| are the reason Python is still in the picture today.
|
| It will be interesting to see, moving forward, what
| languages survive. A 15% perf increase seems nice, until
| you realize that you get a 10x increase porting to Rust
| (and the AI does it for you).
|
| Maybe library use/popularity is somewhat related to
| backwards compatibility.
|
| Disclaimer: I teach Python for a living.
| kccqzy wrote:
| Python does not take backwards compatibility seriously. 2
| to 3 is a big compatibility break. But things like
| `map(None, seq1, seq2)` also broke; such deliberate
| compatibility break is motivated by no more than
| aesthetic purity.
| g947o wrote:
| Money.
| hardwaregeek wrote:
| For what it's worth Ruby's JIT took several different
| implementations, definitely struggled with Rails compatibility
| and literally used some people's PhD research. It wasn't a
| trivial affair
| bawolff wrote:
| I thought php hasn't shipped jit yet (as in its behind a
| disabled by default config)
| SahAssar wrote:
| PHP 8 shipped with JIT on by default unless I'm mistaken.
| fridder wrote:
| For better or for worse they have been very consistent
| throughout the years that they don't want want to degrade
| existing performance. It is why the GIL existed for so long
| fluidcruft wrote:
| (what are blueberry, ripley, jones and prometheus?)
| max-m wrote:
| The names of the benchmark runners.
| https://doesjitgobrrr.com/about
| fluidcruft wrote:
| So the biggest gains so far are on Windows 11 Pro of (x86_64)
| ~20%? Is that because Windows was bad as a baseline
| (promethius)? It doesn't seem like the x86_64/Linux has
| improved as dramatically ~5% (ripley). I'm just surprised OS
| has that much of an effect that can be attributed to JIT vs
| other OS issues.
| raddan wrote:
| It's hard to say whether it's Windows related since the two
| x86_64 machines don't just run different OSes, they also
| have different processors, from different manufacturers. I
| don't know whether an AMD Ryzen 5 3600X versus Intel
| i5-8400 have dramatically different features, but unlike a
| generic static binary for x86_64, a JIT could in principle
| exploit features specific to a given manufacturer.
| mkl wrote:
| Yes, the graphs are incomprehensible because those are not
| defined in the article. They turn out to be different physical
| machines with different architectures:
| https://doesjitgobrrr.com/about blueberry
| (aarch64) Description: Raspberry Pi 5, 8GB RAM, 256GB SSD
| OS: Debian GNU/Linux 12 (bookworm) Owner: Savannah
| Ostrowski ripley (x86_64) Description: Intel
| i5-8400 @ 2.80GHz, 8GB RAM, 500GB SSD OS: Ubuntu 24.04
| Owner: Savannah Ostrowski jones (aarch64)
| Description: Apple M3 Pro, 18GB RAM, 512GB SSD OS: macOS
| Owner: Savannah Ostrowski prometheus (x86_64)
| Description: AMD Ryzen 5 3600X @ 3.80GHz, 16GB RAM OS:
| Windows 11 Pro Owner: Savannah Ostrowski
| nonameiguess wrote:
| The immediate question has been answered, but what about the
| names? The latter three are obvious references to the Alien
| universe, but what relationship does blueberry have to them?
| luhn wrote:
| I assume Blueberry is a nod to the machine being a Raspberry
| Pi.
| killingtime74 wrote:
| Sorry but the graphs are completely unreadable. There are four
| code names for each of the lines. Which is jit and which is
| cpython?
| mkl wrote:
| They are all JIT on different architectures, measured relative
| to CPython. https://doesjitgobrrr.com/about: blueberry is
| aarch64 Raspberry Pi, ripley is x86_64 Intel, jones is aarch64
| M3 Pro, prometheus is x86_64 AMD.
| owaislone wrote:
| Oh man, Python 2 > 3 was such a massive shift. Took almost half a
| decade if not more and yet it mainly changing superficial syntax
| stuff. They should have allowed ABIs to break and get these
| internal things done. Probably came up with a new, tighter API
| for integrating with other lower level languages so going forward
| Python internals can be changed more freely without breaking
| everything.
| gjvc wrote:
| [delayed]
___________________________________________________________________
(page generated 2026-03-17 23:00 UTC)