Tangential, but I practically owe my life to this guy. He wrote the flask mega tutorial in what I followed religiously to launch my first website. Then right before launch, in the most critical part of my entire application; piping a fragged file in flask. He answered my stackoverflow question, I put his fix live, and the site went viral. Here's the link for posterity's sake https://stackoverflow.com/a/34391304/4180276
Off-topic, but I absolutely loathe new Flask logo. Old one[0] has this vintage, crafty feel. And the new one[1] looks like it was made by a starving high schooler experimenting with WordArt.
(n.b. The Cracker Barrel Rebellion is sometimes associated with MAGA. I am very far from that, but I have to respect when people of any political stripe get something right.)
the funny thing about the Cracker Barrel brouhaha is that the new one still looked like something you'd find on a pack of matches from a hotel bar in the 70s.
Fun fact: so did most focus groups and (I think?) blind taste tests when it was just presented as a new drink, but they tended to be horrified by the idea of it actually replacing classic Coke. The problem with that switch was mostly psychological / cultural, not chemical.
Also, Diet Coke, which remains quite popular, is still based on the New Coke formula except with the sweetener swapped out. The no-calorie version of classic Coke is Coke Zero. The Coca-Cola Company has been working to increase Coke Zero's popularity, and it is now much more popular than it used to be, but I think Diet Coke continues to be more popular than Coke Zero even now.
> According to research obtained by the Wall Street Journal from PeakMetrics, 44.5% of X posts about Cracker Barrel on Aug. 20 (when the new logo began to go viral), were posted by “bots or likely bots,” rising to 49% at the peak of the controversy.
I wonder how much this differs from the percentage for any trending topic on X?
The vast majority of Twitter posts are by bots, so 44.5% seems like a higher proportion of humans than usual. The Cracker Barrel thing was a hot topic amongst people I know for a good 48 hours.
It's more interesting to me how, without fail, a comment always pops in at the mention of Cracker Barrel to say "those were bots, fellow human."
Did anyone short Cracker Barrel stock? If not, I have a hard time seeing why bots would have any interest in investing the time/money. There also didn't seem to be any political clout being gained by the complaints.
More real-world is that I know tons of friends/relatives in the South and I don't know of even ONE that liked the redesign.
I recall reading somewhere about some investor who wanted to take control of cb who drove this, so less shorting and more opportunistic drive down the price to buy more shares at a lower price.
Yes. Sardar Biglari, who's an activist investor and the CEO and owner of Steak'n'Shake, has been pushing for more control over Cracker Barrel for several years. He amplified some of the backlash against Cracker Barrel.
Russia has gotten VERY good at amplifying any cultural differences or controversies in order to break US politics (and many other countries). If you hadn't noticed it has been VERY effective.
Bots aren't necessarily aimed to promote "glorious motherland" directly, there are probably hundreds of people on a payroll searching for easy, popular targets to wreak havoc.
This logo is bad.. not even talking about the mark, the fonts are wtf. Uppercase 'F' shorter than the lower 'l' and 'k', the 'a' and the 'k' bad, even the lower bar on the 'f' angle is just... eww. And then the mark. I dont get any of this.
> the fonts are wtf. Uppercase 'F' shorter than the lower 'l' and 'k'
Just like in the old one. That is not strange in the slightest, it is a very common feature of typefaces that the ascenders of lower case letters overshoot the height of uppercase. That is one of the ways to distinguish an uppercase i from a lower case L.
> And then the mark. I dont get any of this.
They look to be following the Material Design logo trend that was in fashion a while ago. Following trends in logo design is never a good idea, it makes them look outdated soon.
I didn't know that they have the new logo before reading your comment. Been 2 years since I last searched flask but yeah the old logo was vintage and I also preferred the old logo and the new logo feels mid/sucks.
> Old logo is impossible to resize and present on any assets that aren't rectangular. Flask isn't a country podunk restaurant
You're measuring it by irrelevant measures. This is like when all the terrible Western game devs criticised Elden Ring because it didn't have "good UX".
What the…? I guess I’ve been reaching for FastAPI instead of flask these days because I had no idea this happened. Didn’t all the pallets projects have the old timey logos? I wonder what happened.
In fact, when I saw the new logo, the first thing that came to my mind was Brigadier General Jack D. Ripper in Dr. Strangelove saying "I deny them my essence."
When I was in college I discovered the flask mega tutorial and fell in love with programming. Switched from an economics degree to software engineering and now work in the industry.
Absolutely love seeing like a dozen people piling on Mr Grinberg to show gratitude for his work, and indeed the even little things he does to help uplift others in the field. It’s a good reminder that a small helpful contribution, or bit of teaching given at the right time, can be so valuable!
Amazing to see all of the people thanking you! Great to see that gratitude is still alive and well. You seemed to have touched a lot of lives through that mega tutorial! wow!
I also want to chime in and say how you changed my life. I did the same Flask megatutorial and that led me to leaving helpdesk and becoming a support engineer. Years later, and I'm now in big tech. Thanks Miguel!
To limit the amount of languages we support I recently rewrote one of our backend services from Go (with SQLC) to Python. I hadn't worked with Python "web" for a while and started with Litestar and also their Advanced-Alchemy. Part of the reason was that their DTO's and dataclasses seemed like a good way to skip Pydantic. Anyway, once models became complext it wasn't easy to skip Pydantic and it also wasn't easy to deal with Advanced Alchemy. One afternoon I got so annoyed with it I rewrote everything with Django Ninja. It took me 4-5 hours that evening to recreate all the previous weeks stuff with Django because of how good the batteries included are.
I'm not sure I'd ever use any other web framework than Django going forward, and I'm not using half of it (including the admin). I think Litestar is great by the way, Django is just so easy to produce with.
For anyone else wondering whether to click to find what "fragged file" means: no, it's not about Quake and the linked page does not mention 'frag' at all. The question asks how to stream a file to the client in Flask as opposed to reading it all into memory at once and then sending it on. I figured as much (also because e.g. IP fragmentation) but first time I hear this alternative term for streaming
The accessibility of this material and also the broader python ecosystem is truly incredible. After reflecting on this recently, started finding ways to give back/donate/contribute.
Yet another appreciation story for Miguel’s mega tutorial. In 2017 I used it to create our wedding site and learn a bit of web dev (my background is in data science). To motivate me to actually do it I used the strategy the fund the then occurring refactoring of the tutorial. I am still very fond and proud of that first time I actually went and funded some open source effort, it gives you back more than you might expect
> Brazil Advances Criminal Prosecution of American Yout.com Operator
Touché! I see sibling comments assuming I was being sarcastic (without mandatory sarcasm tag!), but what I was really hoping for was more backstory like this. I guess it depends on how you read things in your head.
Please don’t make benchmarks with timing inside the loop creating a sum. Just time the loop and divide by the number. Stuff happens getting the time and the jitter can mess with results.
The real world benchmark is measuring it from invocation, both for cold launches and 'hot' (data cached from the last run).
Interestingly I might have only ever used the time (shell) builtin command. GNU's time measuring command prints a bunch of other performance stats as well.
Python 3.11 on Debian is around 21 MB installed size (python3.11-minimal + libpython3.11-minimal + libpython3.11-stdlib), not counting common shared dependencies like libc, ncurses, liblzma, libsqlite3, etc.
Looking at the embeddable distribution for Windows (32-bit), Python 3.11 is 17.5 MB unpacked, 3.13 is slightly smaller at 17.2 MB and 3.14 is 18.4 MB (and adds the _zstd and _remote_debugging modules).
This is the "standard" configure + make + make install, which includes libpython.a, header files, Python's own tests (python -m test), plus __pycache__, and debug symbols. Distros of course may split it up into multiple packages, split out debug symbols, etc.
See `docker run -it --rm -w /store ghcr.io/spack/all-pythons:2025-10-10`.
To be fair, the main contributors are tests and the static library.
The biggest thing PyPy adds is JIT compilation. This is precisely what the project to add JIT to CPython is working on these days. It's still early days for the project, but by 3.15 there's a good chance we'll see some really great speedups in some cases.
It's worth noting that PyPy devs are in the loop, and their insights so far have been invaluable.
> That said, I wonder if GIL-less Python will one day enable GIL-less C FFI? That would be a big win that Python needs.
I'm pretty sure that is what freethreading is today? That is why it can't be enabled by default AFAIK, as several C FFI libs haven't gone "GIL-less" yet.
Can you clarify the concern? Starting from C I've come to expect many dialects across many compiler implementations. It seems healthy and encourages experimentation. Is it not a sign of a health language ecosystem?
It's a culture thing. C culture is all about rolling your own bespoke solution, which encourages the formation of dialects. On the other hand, Python culture is all about "There should be one-- and preferably only one --obvious way to do it.": https://peps.python.org/pep-0020/#the-zen-of-python
These days you could probably build a pretty performant numpy like using shared memory with Arrow format and IPC for control.
Though it would be considerably more complex and not at all easier than FFI...
Well, they added an experimental JIT so that is one step closer to PyPy? Though would assume the trajectory is build a new JIT vs. merge in PyPy, but hopefully people learned a lot from PyPy.
For me the "criminal" thing is that Pypy exists on a shoestring and yet delivers the performance and multithreading that others gradually try to add to cpython.
It's problem is, IMO, compatibility. Long ago I wanted to run it on yocto but something or other didn't work. I think this problem is gradually disappearing but it could be solved far more rapidly with a bit of money and effort probably.
> [Donald Knuth] firmly believes that having an unchanged system that will produce the same output now and in the future is more important than introducing new features
This is such a breath of fresh air in a world where everything is considered obsolete after like 3 years. Our industry has a disease, an insatiable hunger for newness over completeness or correctness.
There's no reason we can't be writing code that lasts 100 years. Code is just math. Imagine having this attitude with math: "LOL loser you still use polynomials!? Weren't those invented like thousands of years ago? LOL dude get with the times, everyone uses Equately for their equations now. It was made by 3 interns at Facebook, so it's pretty much the new hotness." No, I don't think I will use "Equately", I think I'll stick to the tried-and-true idea that has been around for 3000 years.
Forget new versions of everything all the time. The people who can write code that doesn't need to change might be the only people who are really contributing to this industry.
> There's no reason we can't be writing code that lasts 100 years. Code is just math.
In theory, yes. In practice, no, because code is not just math, it's math written in a language with an implementation designed to target specific computing hardware, and computing hardware keeps changing. You could have the complete source code of software written 70 years ago, and at best you would need to write new code to emulate the hardware, and at worst you're SOL.
Software will only stop rotting when hardware stops changing, forever. Programs that refuse to update to take advantage of new hardware are killed by programs that do.
This is a total red herring, x86 has over 30 years of backwards compatability and the same goes for the basic peripherals.
The real reason for software churn isn't hardware churn, but hardware expansion. It's well known that software expands to use all available hardware resources (or even more, according to Wirth's law).
30 years ago, right before Windows 95 came out, Windows was a 16-bit OS and the modern versions of Windows no longer support 16-bit programs. PCIe came out only in 2003, and I don't know that PCIe slots can support PCI. SATA is also from 2003. Even USB originally came out in 1996, and the only pre-USB connector slot I have on my computer is a PS/2 port (which honestly surprises me). For monitor connections, VGA and DVI (1999!) have died off, and their successors (HDMI, DisplayPort) are only in the 2000's.
So pretty much none of the peripherals--including things like system memory and disk drives, do note--from a computer in 1995 can talk using any of the protocols a modern computer supports (save maybe a mouse and keyboard) and require compatibility adapters to connect, while also pretty much none of the software works without going through custom compatibility layers. And based on my experience trying to get a 31-year old Win16 application running on a modern computer, those compatibility layers have some issues.
PCIe is mostly backwards compatible with PCI, and bridge chips used to be quite common. ISA to PCI is harder, but not unheard of.
"SATA" stands for "serial ATA", and has the same basic command set as the PATA from 1984 - bridge chips were widely used. And it all uses SCSI, which is also what USB Mass Storage Devices use. Or if you're feeling fancy, there's a whole SCSI-to-NVMe translation standard as well.
HDMI is fully compatible with single-land DVI-D, you can find passive adapters for a few bucks.
There's one port you forgot to mention: ethernet! A brand-new 10Gbps NIC will happily talk with an ancient 10Mbps NIC.
It might look different, but the pc world is filled with ancient technology remnants, and you can build some absolutely cursed adapter stacks. If anything, the limiting factor is Windows driver support.
Slight caveat that a lot of Ethernet PHYs > 1G don't go down to 10 Mb, my some don't go to 100 Mb, and some are only the speed they want to be (though luckily that's not very common). There exist 6-speed PHYs (10,100,1000,2500,5000,10000) but that doesn't mean everything will happily talk
The basic peripherals (keyboard and monitor) of today still present the same interface as they did back in the IBM PC era.
Everything else is due to massive hardware expansion, not hardware churn.
How often do you update your drivers compare to your typical internet connected app?
Software that handles the idiosyncrasies of the hardware (aka drivers) generally has a much longer lifespan than most other software; I don't see how you can reasonably say hardware breaking backwards compatibility is why software keeps changing.
I don’t think I can take that claim by itself as necessarily implying the cause is hardware. Consumer OSes were on the verge of getting protected memory at that time, as an example of where things were, so if I imagine “take an old application and try to run it” then I am immediately imagining software problems, and software bit rot is a well-known thing. If the claim is “try to run Windows 95 on bare metal”, then…well actually I installed win98 on a new PC about 10 years ago and it worked. When I try to imagine hardware changes since then that a kernel would have to worry about, I’m mostly coming up with PCI Express and some brave OEMs finally removing BIOS compatibility and leaving only UEFI. I’m not counting lack of drivers for modern hardware as “hardware still changes” because that feels like a natural consequence of having multiple vendors in the market, but maybe I could be convinced that is a fundamental change in and of itself…however even then, that state of things was extremely normalized by the 2000s.
Drivers make up a tiny portion of the software on our computer by any measure (memory or compute time) and they're far longer lasting than your average GUI app.
On the other hand, the main reason why Y2K happened was because a lot of major orgs would rather emulate software from the 60s forever than rewrite it. I'm talking like ancient IBM mainframe stuff, running on potentially multiple layers of emulation and virtualization.
We rewrite stuff for lots of reasons, but virtualization makes it easy enough to take our platforms with us even as hardware changes.
Pretty sure if I downloaded and compiled Tcl/Tk 7.6.x source code on a modern Linux box, it would run my Tcl/Tk 7.6.x "system monitor" code from 1995 or 1996 just fine.
Do you have any examples that aren't because of the OS (as in, not trying to run a 90's game on Windows 11) or specialized hardware (like an old Voodoo GPU or something)?
> x86 doesn't have magical backwards compatibility powers.
I never said it did; other ISAs have similar if not longer periods of backwards compatability (IBM's Z systems architecture is backwards compatible with the System/360 released in 1964).
> The amazing backwards compatibility of Windows is purely due to the sheer continuous effort of Microsoft.
I never mentioned Windows but it's ridiculous to imply its backwards compatability is all on Microsoft.
Show me a single example of a backwards breaking change in x86 that Windows has to compensate for to maintain backwards compatability.
> The shift from 16-bit to 32-bit protected mode with the Intel 80386 processor that fundamentally altered how the processor managed memory.
I said x86 has "over 30 years of backwards compatibility".
The 80386 was released in 1985, 40 years ago :)
> Intel 80286 introduced a 24-bit address bus to support more memory, but this broke the address wraparound behavior of the 8086.
This is the only breaking change in x86 that I'm aware of and it's a rather light one as it only affected programs relying on an exactly 2^16 memory space.
And, again, that was over 40 years ago!
> The shift to x86-64 that Microsoft had to compensate with emulation and WOW64
No, I don't think so. A x86-64 CPU starts in 32 bit mode and then has to enter 64 bit mode (I'd know, I spent many weekends getting that transition right for my toy OS). This 32 bit mode is absolutely backwards compatible AFAIK.
WOW64 is merely a part of Microsoft's OS design to allow 32 bit programs to do syscalls to a 64 bit kernel, as I understand it.
The bare minimum cost of software churn is the effort of one human being, which is far less than hardware churn (multiple layers of costly design and manufacturing). As a result, we see hardware change gradually over the years, while software projects can arbitrarily deprecate, change, or remove anything at a whim. The dizzying number of JS frameworks, the replacement of X with Wayland or init with systemd, removal of python stdlib modules, etc. etc. have nothing to do with new additions to the x86 instruction set.
TeX is written in a literate programming style which is more akin to a math textbook than ordinary computer code, except with code blocks instead of equations. The actual programming language in the code blocks and the OS it runs on matters a lot less than in usual code where at best you get a few sparse comments. Avoiding bit rot in such a program is a very manageable task. In fact, iirc the code blocks which end up getting compiled and executed for TeX have been ported from Pascal to C at some point without introducing any new bugs.
The C version of TeX is also terrible code in the modern day (arbitrary limits, horrible error handling, horrible macro language, no real Unicode support, etc. etc), hence LuaTeX (et al.) and Typst and such.
The backward-compat story is also oversold because, yes, baseline TeX is backward compatible, but I bet <0.1% of "TeX" document don't use some form of LaTeX and use any number of packages... which sometimes break at which point the stability of base TeX doesn't matter for actual users. It certainly helps for LaTeX package maintainers, but that doesn't matter to users.
Don't get me wrong, TeX was absolutely revolutionary and has been used for an insane amount of scientific publishing, but... it's not great code (for modern requirements) by any stretch.
Each new layer of emulation is new code that needs to be written that wasn't required when the original program in question was written. It's a great approach for software preservation, but the fact that it's necessary shows why the approach of "if it ain't broke, don't fix it" doesn't work. The context of computing is changing around us at all times, and hardware has a finite lifespan.
Eh. Emulators are often tiny in comparison to the programs they emulate. Especially when performance isn't so much of a concern - like when you're emulating software written for computers from many decades ago. A good emulator can also emulate a huge range of software. Just look at programs like dosbox and the like. Or Apple's great work with Rosetta and Rosetta2 - which are both complex, but much less complex than all the software they supported. Software like Chrome, Adobe Photoshop and the Microsoft office suite.
Arguably modern operating systems are all sort of virtual machine emulators too. They emulate a virtual computer which has special instructions to open files, allocate memory, talk to the keyboard, make TCP connections, create threads and so on. This computer doesn't actually exist - its just "emulated" by the many services provided by modern operating systems. Thats why any windows program can run on any other windows computer, despite the hardware being totally different.
Are you by chance a Common Lisp developer? If not, you may like it (well, judging only by your praise of stability).
Completely sidestepping any debate about the language design, ease of use, quality of the standard library, size of community, etc... one of its strengths these days is that standard code basically remains functional "indefinitely", since the standard is effectively frozen. Of course, this requires implementation support, but there are lots of actively maintained and even newer options popping up.
And because extensibility is baked into the standard, the language (or its usage) can "evolve" through libraries in a backwards compatible way, at least a little more so than many other languages (e.g. syntax and object system extension; notable example: Coalton).
Of course there are caveats (like true, performant async programming) and it seems to be a fairly polarizing language in both directions; "best thing since sliced bread!" and "how massively overrated and annoying to use!". But it seems to fit your description decently at least among the software I use or know of.
I respect and understand the appeal of LISP. It is a great example of code not having to change all the time. I personally haven't had a compelling reason to use it (post college), but I'm glad I learned it and I wouldn't be averse to taking a job that required it.
While writing "timeless" code is certainly an ideal of mine, it also competes with the ideals of writing useful code that does useful things for my employer or the goals of my hobby project, and I'm not sure "getting actual useful things done" is necessarily LISP's strong suit, although I'm sure I'm ruffling feathers by saying so. I like more modern programming languages for other reasons, but their propensity to make backward-incompatible changes is definitely a point of frustration for me. Languages improving in backward-compatible ways is generally a good thing; your code can still be relatively "timeless" in such an environment. Some languages walk this line better than others.
I think, the "useful" part is more covered by libraries than everything else, and the stability and flexibility of the core language certainly helps with that. Common Lisp is just not very popular (as every lisp) and does not have a very big ecosystem, that's it.
Another point for stability is about how much a runtime can achieve if it is constantly improved over decades. Look where SBCL, a low-headcount project, is these days.
We should be very vigilant and ask for every "innovation" whether it is truly one. I think it is fair to assume for every person working in this industry for decades that the opinion would be that most innovations are just fads, hype and resume-driven development - the rest could be as well implemented as a library on top of something existing. The most progress we've had was in tooling (rust, go) which does not require language changes per se.
I think, the frustrating part about modern stacks is not the overwhelming amount of novelty, it is just that it feels like useless churn and the solutions are still as mediocre or even worse that what we've had before.
Stability is for sure a very seducing trait. Also I can totally understand the fatigue of the chase for the next almost already obsolete new stuff.
>There's no reason we can't be writing code that lasts 100 years.
There are many reason this is most likely not going to happen. Code despite best effort to achieve separation of concern (in the best case) is a highly contextual piece of work. Even with a simple program with no external library, there is a full compiler/interpreter ecosystem that forms a huge dependency. And hardware platforms they abstract from are also moving target. Change is the only constant, as we say.
>Imagine having this attitude with math: "LOL loser you still use polynomials!? Weren't those invented like thousands of years ago?
Well, that might surprise you, but no, they weren't. At least, they were not dealt with as they are thought and understood today in their contemporary most common presentation. When Babylonians (c. 2000 BCE) solved quadratic equation, they didn't have anything near Descartes algebraic notation connected to geometry, and there is a long series evolution in between, and still to this days.
Mathematicians actually do make a lot of fancy innovative things all the time. Some fundamentals stay stable over millennia, yes. But also some problem stay unsolved for millennia until some outrageous move is done out of the standard.
Don't know about 100 years, but old static web page from lat 90's with js on wayback machine still works. There might be something to this static html css to archive content maybe even little programs.
Yes, and we only need a browser to achieve that, the kind of piece of software well known to be small, light and having only sporadic changes introduced into them. :D
That's actually a good moment to wander about what an amazing they are, really.
To be fair, if math did have version numbers, we could abandon a lot of hideous notational cruft / symbol overloading, and use tau instead of pi. Math notation is arguably considerably worse than perl -- can you imagine if perl practically required a convention of single-letter variable names everywhere? What modern language designer would make it so placing two variable names right next to each other denotes multiplication? Sheer insanity.
Consider how vastly more accessible programming has become from 1950 until the present. Imagine if math had undergone a similar transition.
Math personally "clicked" to me when I started to use Python and R for mathematical operations instead of the conventional arcane notation. I did make me wonder why we insist on forcing kids and young adults to struggle through particularly counter-intuitive ways to express mathematical concepts just because of historical baggage, and I am glad to hear now that I am not the only one who thinks this way.
Mathematical notation evolved to its modern state over centuries. It's optimized heavily for its purpose. Version numbers? You're being facetious, right?
Without version numbers, it has to be backwards-compatible, making it difficult to remove cruft. What would programming be like if all the code you wrote needed to work as IBM mainframe assembly?
Tau is a good case study. Everyone seems to agree tau is better than pi. How much adoption has it seen? Is this what "heavy optimization" looks like?
It took hundreds of years for Arabic numerals to replace Roman numerals in Europe. A medieval mathematician could have truthfully said: "We've been using Roman numerals for hundreds of years; they work fine." That would've been stockholm syndrome. I get the same sense from your comment. Take a deep breath and watch this video: https://www.youtube.com/watch?v=KgzQuE1pR1w
>You're being facetious, right?
I'm being provocative. Not facetious. "Strong opinions, weakly held."
> Without version numbers, it has to be backwards-compatible
If there’s one thing that mathematical notation is NOT, it’s backwards compatible. Fields happily reuse symbols from other fields with slightly or even completely different meanings.
Widely used for denoting division in Anglophone countries, it is no longer in common use in mathematics and its use is "not recommended". In some countries, it can indicate subtraction.
~ (tilde)
1. Between two numbers, either it is used instead of ≈ to mean "approximatively equal", or it means "has the same order of magnitude as".
2. Denotes the asymptotic equivalence of two functions or sequences.
3. Often used for denoting other types of similarity, for example, matrix similarity or similarity of geometric shapes.
4. Standard notation for an equivalence relation.
5. In probability and statistics, may specify the probability distribution of a random variable. For example, X∼N(0,1) means that the distribution of the random variable X is standard normal.
6. Notation for proportionality. See also ∝ for a less ambiguous symbol.
> Fields happily reuse symbols from other fields with slightly or even completely different meanings.
Symbol reuse doesn't imply a break in backwards compatibility. As you suggest with "other fields", context allows determining how the symbols are used. It is quite common in all types of languages to reuse symbols for different purposes, relying on context to identify what purpose is in force.
Backwards incompatibility tells that something from the past can no longer be used with modern methods. Mathematical notation from long ago doesn't much look like what we're familiar with today, but we can still make use of it. It wasn't rendered inoperable by modern notation.
If the compiler forbade syntactic ambiguity from implicit multiplication and had a sensible LSP allowing it to be rendered nicely, I don't think that'd be such a bad thing. Depending on the task at hand you might prefer composition or some other operation, but when reducing character count allows the pattern recognition part of our brain to see the actual structure at hand instead of wading through character soup it makes understanding code much easier.
> There's no reason we can't be writing code that lasts 100 years. Code is just math. Imagine having this attitude with math: "LOL loser you still use polynomials!? Weren't those invented like thousands of years ago? LOL dude get with the times, everyone uses Equately for their equations now. It was made by 3 interns at Facebook, so it's pretty much the new hotness." No, I don't think I will use "Equately", I think I'll stick to the tried-and-true idea that has been around for 3000 years.
Not sure this is the best example. Mathematical notation evolved a lot in the last thousand years. We're not using roman numerals anymore, and the invention of 0 or of the equal sign were incredible new features.
I agree somewhat with your sentiment and have some nostalgia for a time when software could be finished, but the comment you're replying to was making a joke that I think you may have missed.
Mathematical notion has changed over the years. Is Diophantus' original system of polynomials that legible to modern mathematicians? (Even if you ignore the literally being written in ancient greek part.)
> an insatiable hunger for newness over completeness or correctness.
I understand some of your frustration, but often the newness is in response to a need for completeness or correctness. "As we've explored how to use the system, we've found some parts were missing/bad and would be better with [new thing]". That's certainly what's happening with Python.
It's like the Incompleteness Theorem, but applied to software systems.
It takes a strong will to say "no, the system is Done, warts and missing pieces and all. Deal With It". Everyone who's had to deal with TeX at any serious level can point to the downsides of that.
Worth noting that few people use the TeX executable as specified by Knuth. Even putting aside the shift to pdf instead of dvi output, LaTeX requires an extended TeX executable with features not part of the Knuth specification from 1988.
Btw, equations and polynomials while conceptually are old, our contemporary notation is much younger, dating to the 16th century, and many aspects of mathematical notation are younger still.
Python is pretty much on the other extreme as 3.x → 3.y should be expected to break things, there's no "compability mode" to not break things, and the reasons for the breakage can be purely aestetic bikeshedding
C in contrast generally versions the breaking changes in the standard, and you can keep targeting an older standard on a newer compiler if you need to, and many do
While i think Latex is fantastic, i think there is plenty of low hanging fruit to improve upon it... the ergonomics of the language and its macros aren't great. If nothing else there should be a better investment in tooling and ecosystem.
Kinda related question, but is code really just a math? Is it possible to express things like user input, timings, inteerupts, error handling, etc. as math?
I would slightly sort of disagree that code is just math when you really boil it down, however, if you take a simple task, say, printing hello world to the output, you could actually break that down into a mathematical process. You can mathematically say at time T value of O will be the value of index N of input X, so over a period of time you eventually get "hello world" as the final output
Howeveeerrr.. its not quite math when you break down to the electronics level, unless you go really wild (wild meaning physics math). take a breakdown of python to assembly to binary that flips the transistors doing the thing. You can mathematically define that each transistor will be Y when that value of O is X(N); btw sorry i can't think of a better way to define such a thing from mobile here. And go further by defining voltages to be applied, when and where, all mathematically.
In reality its done in sections. At the electronic level math defines your frequency, voltage levels, timing, etc; at the assembly level, math defines what comparisons of values to be made or what address to shift a value to and how to determine your output; lastly your interpreter determines what assembly to use based on the operations you give it, and based on those assembly operations, ex an "if A == B then C" statement in code is actually a binary comparator that checks if the value at address A is the same as the value at address B.
You can get through a whole stack with math, but much of it has been abstracted away into easy building blocks that don't require solving a huge math equation in order to actually display something.
You can even find mathematical data among datasheets for electronic components. They say (for example) over period T you cant exceed V volts or W watts, or to trigger a high value you need voltage V for period T but it cannot exceed current I. You can define all of your components and operations as an equation, but i dont think its really done anymore as a practice, the complexity level of doing so (as someone not building a cpu or any ic) isnt useful unless youre working on a physics paper or quantum computing, etc etc
If you look at old math treatises from important historical people you'll notice that they use very different notation from the one you're used to. Commonly concepts are also different, because those we use are derived over centuries from material produced without them and in a context where it was traditional to use other concepts to suss out conclusions.
But you have a point, and it's not just "our industry", it's society at large that has abandoned the old in favour of incessant forgetfulness and distaste for tradition and history. I'm by no means a nostalgic but I still mourn the harsh disjoint between contemporary human discourse and historical. Some nerds still read Homer and Cicero and Goethe and Ovid and so on but if you use a trope from any of those that would have been easily recognisable as such by europeans for much of the last millenium you can be quite sure that it won't generally be recognised today.
This also means that a lot of early and mid-modern literature is partially unavailable to contemporary people, because it was traditional to implicitly use much older motifs and riff on them when writing novels and making arguments, and unless you're aware of that older material you'll miss out on it. For e.g. Don Quixote most would need an annotated version which points out and makes explicit all the references and riffing, basically destroying the jokes by explaining them upfront.
Except uh, nobody uses infinitesimals for derivatives anymore, they all use limits now. There's still some cruft left over from the infinitesimal era, like this dx and dy business, but that's just a backwards compatibility layer.
Anyhoo, remarks like this are why the real ones use Typst now. TeX and family are stagnant, difficult to use, difficult to integrate into modern workflows, and not written in Rust.
Are you intentionally leaning into the exact caricature I'm referring to? "Real programmers only use Typstly, because it's the newest!". The website title for Typst when I Googled it literally says "The new foundation for documents". Its entire appeal is that it's new? Thank you for giving me such a perfect example of the symptom I'm talking about.
> TeX and family are stagnant, difficult to use, difficult to integrate into modern workflows, and not written in Rust.
You've listed two real issues (difficult to use, difficult to integrate), and two rooted firmly in recency bias (stagnant, not written in Rust). If you can find a typesetting library that is demonstrably better in the ways you care about, great! That is not an argument that TeX itself should change. Healthy competition is great! Addiction to change and newness is not.
> nobody uses infinitesimals for derivatives anymore, they all use limits now
My point is not that math never changes -- it should, and does. However, math does not simply rot over time, like code seems to (or at least we simply assume it does). Math does not age out. If a math technique becomes obsolete, it's only ever because it was replaced with something better. More often, it forks into multiple different techniques that are useful for different purposes. This is all wonderful, and we can celebrate when this happens in software engineering too.
I also think your example is a bit more about math pedagogy than research -- infinitesimals are absolutely used all the time in math research (see Nonstandard Analysis), but it's true that Calculus 1 courses have moved toward placing limits as the central idea.
>My point is not that math never changes -- it should, and does. However, math does not simply rot over time, like code seems to (or at least we simply assume it does). Math does not age out.
Just in the same sense that CS does not age out. Most concepts stick, but I'm pretty sure you didn't go through Στοιχεία (The Elements) in its original version. I'm also pretty confident that most people out there that use many of the notion it holds and helped to spread never threw their eyes over a single copy of it in their native language.
> I'm pretty sure you didn't go through Στοιχεία (The Elements) in its original version
This is like saying "you haven't read the source code of the first version of Linux". The only reason to do that would be for historical interest. There is still something timeless about it, and I absolutely did learn Euclid's postulates which he laid down in those books, all 5 of which are still foundational to most geometry calculations in the world today, and 4 of which are foundational to even non-Euclidean geometry. The Elements is a perfect example of math that has remained relevant and useful for thousands of years.
So that's it. Just because new languages and framework are rising and fading away, it doesn't mean there is nothing kept all along the way. It just that specific implementation is not the thing that people deem the most important to preserve over time.
I don't know how realistic only using a benchmark that only uses tight loops and integer operations. Something with hashmaps and strings more realistically represents everyday cpu code in python; most python users offload numeric code to external calls.
There is no "realistic" benchmark, all benchmarks are designed to measure in a specific way. I explain what my goals were in the article, in case you are curious and want to read it.
I agree with you, this is not an in depth look, could have been much more rigorous.
But then I think in some ways it's a much more accurate depiction of my use case. I mainly write monte-carlo simulations or simple scientific calculations for a diverse set of problems every day. And I'm not going to write a fast algorithm or use an unfamiliar library for a one-off simulation, even if the sim is going to take 10 minutes to run (yes I use scipy and numpy, but often those aren't the bottlenecks). This is for the sake of simplicity as I might iterate over the assumptions a few times, and optimized algorithms or library impls are not as trivial to work on or modify on the go. My code often looks super ugly, and is as laughably unoptimized as the bubble sort or fib(40) examples (tail calls and nested for loops). And then if I really need the speed I will take my time to write some clean cpp with zmq or pybind or numba.
It's still interesting though. If the most basic thing isn't notably faster, it makes it pretty likely the more complex things aren't either.
If your actual load is 1% python and 99% offloaded, the effect of a faster python might not mater a lot to you, but to measure python you kinda have to look at python
Or have it run some super common use case like a FastAPI endpoint or a numpy calculation. Yes, they are not all python, but it's what most people use Python for.
FastAPI is a web framework, which by definition is (or should be!) an I/O bound process. My benchmark evaluates CPU, so it's a different thing. There are a ton of web framework benchmarks out there if you are interested in FastAPI and other frameworks.
And numpy is a) written in C, not Python, and b) is not part of Python, so it hasn't changed when 3.14 was released. The goal was to evaluate the Python 3.14 interpreter. Not to say that it wouldn't be interesting to evaluate the performance of other things as well, but that is not what I set out to do here.
Numpy is partly written in C but includes a lot of Python code. If you include scipy or scikit learn or pandas, most of the code is python calling primitive numpy C operations. I'd expect that many semi-complex data science programs to benefit from improvement in the python interpreter, especially if they weren't written in super tight numpy code.
That's the thing with Python: A lot of things should be bound by all kinds of limitations, but are in practice often limited by the Python interpreter if not done carefully.
Fundamentally for example, if you're doing some operations on numpy arrays like: c = a + b * c, interpreted numpy will be slower than compiled numba or C++ just because an eager interpreter will never fuse those operations into an FMA.
Really pleasing to see how smooth the non-GIL transition was. If you think about 2->3 python this was positively glorious.
And that it gets into spitting range of standard so fast is really promising too. That hopefully means the part not compatible with it get flushed out soon-ish
> Free-threaded builds of CPython support optionally running with the GIL enabled at runtime using the environment variable `PYTHON_GIL` or the command-line option `-X gil`.
More than 300 comments here and still no convincing answer. Why the community wastes time on trying to make CPython faster when there is pypy which is already much faster? I understand pypy lacks libraries and feature parity with up to date CPython. But… can’t everyone refocus the efforts and just move to pypy to add all the missing bits and then just continue with pypy as the “official python”? Are there any serious technical reasons not to do it?
> Are there any serious technical reasons not to do it?
Yes.
First is startup time. REPL cycle being fast is a big advantage for development. From a business perspective, dev time is more expensive then compute time by orders of magnitude. Every time you make a change, you have to recompile the program. Meanwhile with regular python, you can literally develop during execution.
Second is compatibility. Numpy and pytorch are ever evolving, and those are written a C extensions.
Third is LLMs. If you really want speed, Gemma27bqat that runs on a single 3090 can translate python codebase into C/C++ pretty easily. No need to have any additional execution layer. My friend at Amazon pretty much writes Java code this way - prototypes a bunch of stuff in Python, and then has an LLM write the java code thats compatible with existing intra-amazon java templates.
I really hope I'll never need to touch code written by people who code in python and throws it at a plausible randomiser to get java or C
If you for some reason do this, please keep the python around so I can at least look at whatever the human was aiming at. It's probably also wrong as they picked this workflow, but there's a chance it has something useful
LLMs are there to get the meat of the software in. Fine tuning it is easy when you already have all the syntax written for you. With enough prompting on how you want the code laid out, the modern models do a really good job of getting it right with very minor things you have to tweak.
I get the "old man yells at cloud" vibes from your comment. Who cares how he got the result? I thought our job is to create working software. If this flow works for him and creates code that meets company standards, then more power to him.
However, if the output quality is crap, then well, maybe his creativity should not be rewarded. I've seem hefty amount of Map<Object, Object> in Java, written primarily by JS developers.
As an old man myself, I am quite sure the other old man has a good reason to yell at this particular cloud. Software is tremendously complex. It is one thing to write it, it is another to amend the thousands and thousands of bugs that inevitably follow, and implement the even bigger amount of adjustments and improvements successful software requires. The latter is the bane of any kind of code generation, whether is RAD, no-code, low-code or LLM ported codebases.
Any kind of code generation that proves incredibly productivity in the writing of software is kind of like saying you have a lot of money by maxing out your creditcard. Maybe you can pay it back, maybe you can't. The fact that there is no mention of future debt is exactly the kind of thing that old men get suspicious about.
I'm not saying the old men are correct. I'm just pointing out the reason for the yelling.
Repl I get it. Possibly valid point. Yet I guess same issue are valid to node.js which seems much faster in many cases and still has valid dev experience.
C compatibility / extension compatibility - nope. First, it is an issue of limited resources. Add more devs to pypy team and compatibility bugs gets fixed. Second, aren’t people writing C extensions due to python being slow? Make python fast - as pypy - and for some cases native code won’t be that crucial.
So I don’t see a real issue with pypy that could not be solved by simply moving all the dev efforts from CPython.
So are there political, personal or business issues?
Seriously, though. PyPy is 2-3 versions behind CPython (3.11 vs 3.14) and it's not even 100% compatible with 3.11. Libraries such as psycopg and lxml are not fully supported. It's a hard sell.
But this is exactly my point. The resources pypy has are much smaller. And still for years they managed to follow up being just 2-3 versions behind with features and high on performance.
So why not move all the resources from CPython to close the gap with features faster and replace CPython entirely?
Since this is not happening I expect there to be serious reasons, but I fail to see them. This is what I ask for.
> Are there any serious technical reasons not to do it?
Forget technical reasons, how would you ever do it? It feels like the equivalent of cultural reprogramming "You must stop using your preferred interpreter and halt all your efforts contrary to the one true interpreter". Nah, not going to happen in a free and open source language. Who would have the authority and control to make such a directive?
Yes, there may be technical reasons, but the reason it doesn't happen more than any other is that programming languages are languages spoken by people, and therefore they evolve organically at no one's direction. Even in languages like Python with a strong bent for cultural sameness and a BDFL type direction, they still couldn't control it. Often times, dialects happen for technical reasons, but it's hard to get rid of them on technical grounds.
I think for pure python performance it is significantly faster at least on all the benchmarks I have seen. That said a lot of what people actually do in python calls into libraries that are written in C++ or C, which I believe has a similar performance (when it works) on pypy.
The build of Python that I used has tail calls enabled (option --with-tail-call-interp). So that was in place for the results I published. I'm not sure if this optimization applies to recursive tail calls, but if it does, my Fibonacci test should have taken advantage of the optimization.
That tells you how much I know about the feature. :)
But in any case, I'm positive that the flag was enabled, so my results are with tail calls. I suppose part of the difference between 3.13 and 3.14 could be thanks to this.
Good to know! Thanks for confirming. Yes, I would guess that the tail call interpreter explains part of the difference between 3.13 and 3.14. Previously the overall improvement to the interpreter has been measured at 1-5%, or even 10-15% depending on the compiler version you are using: https://blog.nelhage.com/post/cpython-tail-call/
If your benchmark setup is easy to re-run, it would be awesome to see numbers that compare the tail call interpreter to the build where it is disabled, to isolate how much improvement is due to that.
A lot of Python use cases don't care about CPU performance at all.
In most cases where you do care about CPU performance, you're using numpy or scikit learn or pandas or pytorch or tensorflow or nltk or some other Python library that's more or just a wrapper around fast C, C++ or Fortran code. The performance of the interpreter almost doesn't matter for these use cases.
Also, those native libraries are a hassle to get to work with PyPy in my experience. So if any part of your program uses those libraries, it's way easier to just use CPython.
There are cases where the Python interpreter's bad performance does matter and where PyPy is a practical choice, and PyPy is absolutely excellent in those cases. They just sadly aren't common and convenient enough for PyPy to be that popular. (Though it's still not exactly unpopular.)
It doesn't play nice with a lot of popular Python libraries. In particular, many popular Python libraries (NumPy, Pandas, TensorFlow, etc.) rely on CPython’s C API which can cause issues.
Speaking only for myself, and in all sincerity: every year, there is some feature of the latest CPython version that makes a bigger difference to my work than faster execution would. This year I am looking forward to template strings, zstd, and deferred evaluation of annotations.
Keep in mind that the two scripts that I used in my benchmark are written in pure Python, without any dependencies. This is the sweet spot for pypy. Once you start including dependencies that have native code their JIT is less efficient. Nevertheless, the performance for pure Python code is out of this world, so I definitely intend to play more with it!
Because in the real world, for code where performance is needed, you run the profiler and either find that the time is spent on I/O, or that the time is spent inside native code.
This might have been your experience, but mine has been very different. In my experience a typical python workload is 50% importing python libraries, 45% slow python wrapper logic and 5% fast native code. I spend a lot of time rewriting the python logic in C++, which makes it 100x faster, so the resulting performance approaches "10% fast native logic, 90% useless python imports".
Many simple scripts at my work that more or less just argparse and fire off an HTTP request spend half a minute importing random stuff because of false deps and uncommon codepaths. For some unit tests it's 45 seconds, substantially longer than the time taken to run the test logic.
> Many simple scripts at my work [...] For some unit tests it's 45 seconds
> I spend a lot of time rewriting the python logic in C++, which makes it 100x faster
Nice! Your workplace didn't care to pick a better tool for the job in the past, and it seems to not care what you're doing at present, if you have to spend time rewriting the stuff in C++, instead of picking Nim and calling it a day, in a day.
Have you thought about packing that stuff into an executable or precomputing or preloading it? There's techniques for each of those things that help in some scenarios.
There is more than one PEP related to making imports faster such as PEP 690 or PEP 810. It's definitely a well-known problem. The solution is probably right around the corner.
If imports are slow, you need to not be writing python in the first place, because you are either on limited hardware or you are writing a very performant app.
When it's a drop-in replacement, as in most of my code (and it's dead simple to try if it runs when you use pypy ./main.py), I wouldn't know why you should run the code 5-50% slower for no reason though
IRL you will have CPU-bottlenecked pure Python code too. But it's not enough to take on the unknown risk of switching to a lesser supported interpreter. Worst case you just put in the effort to convert the hot parts to multiprocessing.
I do a bit of performance work and find most often that things are mixed: there’s enough CPU between syscalls that the hardware isn’t being full maximized, but there’s enough I/O the CPUs aren’t pegged either. It is rare that the profiler finds an obvious hotspot that yields an easy win; usually it shows that with heavy refactoring you can make 10% of your load several times faster, and then you’ll need to do the same for the next 10% and so on. That is the more typical real world for me, and in that world Python is really awful when compared to rewrite-it-in-Rust.
This "There are no hot spots, it's just a uniform glowing orange" situation is why Google picked C++ and then later Rust and to some extent why they picked Go too.
For cloud jobs that can be true, but for single threaded dev-in-the-loop work you can't just buy a 100x faster processor than the one on their dev machine, and the latency is expensive workflow friction.
We look periodically and pypy is usually unusable for us due to third-party library support. E.g. psycopg2, at least as of a couple years ago. Have not checked in a while.
I think generally people who care about performance don't tend to write their code in Python to begin with, so the culture of python is much less performance sensitive than is typical even among other interpreted languages like perl, php, ruby or javascript. The people who do need performance, but are still using python, tend to rely on native libraries doing significant numerical calculations, and many of these libraries are not compatible with PyPy. The escape hatch there is to offload more and more of the computation into the native runtime rather than to optimize the python performance.
Because it hasn't been blessed by the PSF. Plus it's always behind, so if you want to use the newest version of framework x, or package y then you're SOL.
Python libraries used to brag about being pure Python and backwards compatible, but during the push to get everyone on 3.x that went away, and I think it is a shame.
I was happy to see it supports a fairly recent Python3 at all now, like Py3.5 or what is it that ships with most of the expected stuff? Works for me, I'd target something like that for compatibility anyway
I keep wondering the same. It's a significant speed-up in most cases and equally easy to (apt) install
For public projects I default the shebang to use `env python3` but with a comment on the next line that people can use if they have pypy. People seem to rarely have it installed but they always have Python3 (often already shipped with the OS, but otherwise manually installed). I don't get it. Just a popularity / brand awareness thing I guess?
It's not easily available in uv.
Even if I installed it outside uv, it always seems significantly out of date. I'm running code in spaces where with uv I can control all the installs of Python, so I don't benefit from using an older release for compatibility.
Personally: cpyext always lags changes in the CPython ABI and headers which my code relies on, or I'm relying on internals which cpyext doesn't implement at all
Because all the heavy number-crunching code is already written in C or Rust or as CUDA kernels, so the actual time spent running Python code is miniscule. If it starts to matter, I would probably reach for Cython first. PyPy is an extremely impressive project, but using it adds a lot of complexity to what is usually a glue language. It is a bit like writing a JIT for Bash.
because it turns out that optimizing performance of a programming language designed for use-cases where runtime performance doesn't matter ... doesn't matter
There's currently talk of adding gigawatts of data center capacity to the grid just for use cases where python dominates development. While a lot of that will be compiled into optimized kernels on CPU or GPU, it only takes a little bit of 1000x slower code to add up to a significant chunk of processing time at training or inference time.
What percentage of the CPU cycles are actually spent running Python though? My impression is _very_ low in production LLM workloads. I think significantly less than 1%. There are almost certainly better places to spend the effort, and if it did matter, I think they would replace Python with something like C++ or Rust.
Might as well take the work that's already done though? I can't think of a logical reason why you'd want to run it at potentially half the speed (depending on the hot code specifics how much, if any, speedup you get of course)
I've never experienced any problems that could be attributed to the speed of my Python runtime. I use Python a lot for internal scripting and devops work, but never in a production environment that scaled beyond a few hundred users. I suspect most Python usecases are like that, and CPython is just the safest option.
The Dutch pronunciation of javascript differs from the English one only in the first syllable. Roughly zero dutchies would insert the Dutch schr- sound in a loanword, and even fewer would do that while leaving the foreign -ipt suffix intact.
Is fold comment a option based on karma or something? I loved the most voted post here on how Miguel helped the guy but, it is unrelated and for the first time I guess I realized there is no fold so I can go to people actually talking about the article...
You got more karma than me, so you're probably just looking past it. It's the [-] button on the right end of the comment header, just to the right of the "next" button.
seems loved languages such as python & ruby (ZJIT | TruffuleRuby) have been getting a lot performance improvements lately. of course JS with v8 kickstarted this - followed by PHP.
so for majority of us folks use what you love - the performance will come.
As someone who was a hardcore python fanboy for a long time, no, no it won't. There are classes of things that you can only reasonably do in a language like rust, or where go/kotlin will save you a crazy amount of pain. Python is fine for orchestration and prototyping, but if it's the only arrow you have in your quiver you're in trouble.
Completely agree, Python is great for its simple syntax, C-interop and great library ecosystem, but it is a pain to debug, deploy, and maintain in more complex use cases, and doesn't play as nicely as other languages with modern stacks (eg. k8s). What is pleasure for the developer (no explicit typing, wild i/o-as-you-go, a library for everything) is pain for the maintainer (useless error messages, sudden exceptions of lacking UAC, dependency hell).
Go, Kotlin and Rust are just significantly more modern and better designed, incorporating the lessons from 90s languages like Python, Ruby and Java.
I know sometimes performance doesn’t matter, and python is certainly useful, but it’s not fast. It can be fast enough and they’ve put a lot of effort into making fast libraries (called in c).
When doing bioinformatics we had someone update/rewrite a tool in java and it was so much faster. Went from a couple days to some like 4 hours of runtime.
Python certainly can be used in production (my experience maintaining some web applications in Java would make me reach for python/php/ruby to create a web backend speed be dammed). Python has some great libraries.
At least Python doesn't have an extremist "100% Pure" ideology like Java, and instead (like TCL and Lua) it's been designed from the ground up for easily integrating with other languages and libraries, embedding, and extending, instead of Java's intolerantly weaponized purity and linguistic supremacy.
Reasons why Sun and Java failed:
Strategy over product. McNealy cast Java as a weapon of mass destruction to fight Microsoft, urging developers to "evangelize Java to fight Microsoft." That fight-first framing made anti-Microsoft positioning the goal line, not developer throughput.
Purity over pragmatism. Sun’s "100% Pure Java" program explicitly banned native methods and dependencies outside the core APIs. In practice, that discouraged bridges to real-world stacks and punished teams that needed COM/OS integration to ship. (Rule 1: "Use no native methods.")
"100% Pure Java" has got to be one of the worst marketing slogans in the history of programming languages, signaling absolutism, exclusion, and gatekeeping. And it was technically just as terrible and destructive an idea that held Java back from its potential as an inclusive integration, extension, and scripting language (especially in the web browser context, since it was so difficult to integrate, that JavaScript happened instead and in spite of Java).
Lua, Python, and even TCL were so much better and successful at embedding and extending applications than Java ever was (or still is), largely because they EMBRACED integration and REJECTED "purity".
Java's extremist ideological quest for 100% purity made it less inclusive and resilient than "mongrel" languages and frameworks like Lua, Python, TCL, SWIG, and Microsoft COM (which Mozilla even cloned as "XP/COM"), that all purposefully enabled easy miscegenation with existing platforms and libraries and APIs instead of insanely insisting everyone in the world rewrite all their code in "100% Pure Java".
That horrible historically troubling slogan was not just a terrible idea technically and pragmatically, but it it also evoked U.S. nativist/KKK's "100% Americanism", Nazi's "rassische Reinheit", "Reinhaltung des Blutes", and "Rassenhygiene", Fascist Italy's "La Difesa della Razza", and white supremacist's "white purity". It's no wonder Scott McNealy is such a huge Trump supporter!
While Microsoft courted integrators. Redmond pushed J/Direct / Java-COM paths, signaling "use Windows features from Java if that helps you deliver." That practicality siphoned off devs who valued getting stuff done over ideological portability.
Community as militia. The rhetoric ("fight," "evangelize") enlisted developers as a political army to defend portability, instead of equipping them with first-rate tooling and sanctioned interop. The result: cultural gatekeeping around "purity" rather than unblocking use cases.
Ecosystem costs. Tooling leadership slid to IBM’s aptly named Eclipse (a ~$40M code drop that became the default IDE), while Sun’s own tools never matched Eclipse’s pull: classic opportunity cost of campaigning instead of productizing.
IBM's Eclipse cast a dark shadow over Sun's "shining" IDE efforts, which could not even hold a candle to Microsoft's Visual Studio IDE that Sun reflexively criticized so much without actually bothering to use and understand the enemy.
At least Microsoft and IBM had the humility to use and learn from their competitor's tools, in the pursuit of improving their own. Sun just proudly banned them from the building, cock-sure there was nothing to learn from them. And now we are all using polyglot VSCode and Cursor, thanks to Microsoft, instead of anything "100% Pure" from Sun!
Litigation drain. Years of legal trench warfare (1997 suit and 2001 settlement; then the 2004 $1.6B peace deal) defended "100% Pure Java" but soaked time, money, and mindshare that could have gone to developer-facing capabilities.
Optics that aged poorly. The very language of "purity" in "100% Pure Java" read as ideological and exclusionary to many -- whatever Sun's presumed intent -- especially when it meant "rewrite in Java, don’t integrate." The cookbook literally codified "no native methods," "no external libraries," and even flagged Runtime.exec as generally impure.
McNealy’s self-aggrandizing war posture did promote Java’s cross-platform ideal, but it de-prioritized developer pragmatism -- stigmatizing interop, slow-rolling mixed-language workflows, and ceding tools leadership -- while burning years on lawsuits. If your priority was "ship value fast," Sun’s purity line often put you on the wrong side of the border wall.
And now finally, all of Java's remaining technical, ideological, and entrenched legacy enterprise advantages don't matter any more, alas, because they are all overshadowed by the unanthropomorphizable lawnmower that now owns it and drives it towards the singular goal of extracting as much profit from it as possible.
Very nice post - it's good to see benchmarks done for humans.
For fun, I tried this in Raku:
(0, 1, *+* ... *)[40] #0.10s user 0.03s system 63% cpu 0.214 total
lol
Seriously, Python is doing great stuff to squeeze out performance from a scripting language. Realistically, Raku has fewer native libraries (although there is Inline::Python) and the compiler still has a lot of work to get the same degree of optimisation (although one day it could compare).
EDIT: for those who have commented, yes you are correct … this is a “cheat” and does not seek to state that Raku is faster than Python - as I said Raku still has a lot of work to do to catch up.
I take it this is supposed to be the equivalent of fib(40), which ran on the author's system in Pyπ in 6.59 seconds and apparently on yours, with Raku, in 0.21?
Do you have the same hardware as the author or should one of you run the other's variant to make this directly comparable?
No, this is very much not the same. The Raku version is like writing this in Python:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a+b
And taking the 40th element. It's not comparable at all to the benchmark, that's deliberately an extremely slow method of calculating fibonacci numbers for the purpose of the benchmark. For this version, it's so fast that the time is dominated by the time needed to start up and tear down the interpreter.
Well, sure; you're using dynamic programming, while the stress test Python Fibonacci code is deliberately using recursion without memoization — it makes function calls proportionate to the number computed. Most of the time you're seeing in the Raku code is the interpreter startup. Python doesn't have syntax strongly oriented towards that sort of trick (it's not as strong of a second-best APL as it is a second-best Lisp or Haskell), but:
$ python -m timeit "x = (1, 0); [x[0] for _ in range(40) if (x := (x[0] + x[1], x[0]))][-1]"
50000 loops, best of 5: 4 usec per loop
(Or a "lazy iterator" approach:)
$ python -m timeit --setup 'from itertools import islice, count' 'x = (1, 0); next(islice((x[0] for _ in count() if (x := (x[0] + x[1], x[0]))), 40, None))'
50000 loops, best of 5: 5.26 usec per loop
That >2x performance increase over 3.9 in the first test is pretty impressive. A narrow use case for sure, but assuming you can leave your code completely alone and just have it run on a different interpreter via a few CLI commands, that's a nice bump.
Very interesting post, thanks for putting it together.
Rust is indeed quite fast, I thought NodeJS was much better tbh., although it's not bad. I'd be interested to learn what's holding it back because I've seen many implementations where V8 can get C++-like performance (I mean it's C++ after all). Perhaps there's a lot of overhead in creating/destroying temporary objects.
> V8 can get C++-like performance (I mean it's C++ after all)
I don’t think that follows. Python is written in C, but that doesn’t mean it can get C-like performance. The sticking point is in how much work the runtime has to do for each chunk of code it has to execute.
(Edit: sorry, that’s in reply to another child content. I’m on my phone in a commute and tapped the wrong reply button.)
One reason is that I did not spend much time optimizing the Node and Rust versions, I just translated the Python logic as directly and quickly as I could. At least I did not ask an LLM to do it for me, which I hope counts. ;-)
V8 gets C++-like performance when it is getting code that JITs very well. This is typically highly-numeric code, even sometimes tuned specifically for the JIT. This tends to cause a great deal of confusion when people see the benchmarks for that highly numeric code and then don't understand why their more conventional code doesn't get those speeds. It's because those speeds only apply to code you're probably not writing.
If you are writing that sort of code, then it does apply; the speed for that code is real. It's just that the performance is much more specific than people think it is. In general V8 tends to come in around the 10x-slower-than-C for general code, which means that in general it's a very fast scripting language, but in the landscape of programming languages as a whole that's middling single-thread performance and a generally bad multiprocessing story.
For the bubble sort implementation, it's due to the use of the destructuring assignment in the benchmark code. When swapping to a regular swap using a temporary variable, the benchmark runs more than 4 times faster on my machine. Still not at Rust level of performance, but a bit closer to it.
I did some recent testing that showed both Lua and LuaJIT-joff (its interpreter-only mode) to be about 2x faster than Python. Both PyPy and full-on LuaJIT were about 10x faster.
Years ago, I even found Ruby to be faster than Python. This was back in the Ruby 2.0 / Python 3.5 days - I'd be interested to know if it's still the case.
According to general benchmarks Apple Silicon is the highest performing CPU for single-threaded work. It'll be hard to confirm how much of a difference the OS factors in but the hardware difference is most likely why.
I feel like Python should be much faster already. With all the big companies using Python and it's huge popularity I would have expected that a lot of money, work and research would be put into making Python faster and better.
The Faster CPython project was from one of "the big companies" and did make significant progress with each version of Python, even if some of its more ambitious goals weren't met. The results of which you're seeing in the benchmarks in this blog post.
There are other languages you can use to make stuff go fast. Python isn't for making stuff go fast. Its for rapid dev, and that advantage matters way more when you already are going to be slow due to waiting for network response
This has always confused me... is Python really that much better at rapid dev? I work on a Python project and every day I wish the people that started the project had chosen a different language that actually scaled well with the problem rather than Python, which they likely chose because it was for "rapid dev".
I started using Python again recently after a 15 year break. The reason was I started working with LangChain, specifically LangGraph agents. The JavaScript/TypeScript versions are months behind. In the AI world with the progress thats been made recently, months might as well be years.
I’m very glad python is getting faster. But the correct answer to “Is Python Really That Slow?” is unambiguously YES. Unless you’re using some ML library like torch or numpy which spends all its time in optimized C code, python is still EXTREMELY slow. We are going to need a lot of these 10% improvements for python to be comparable to Go, Java, or Node, each of which are about 30x faster on typical computer tasks.
Yeah honestly I don't really care about these benchmarks. Python isn't built for raw performance and that's totally fine! It's the number one choice for prototyping and can do so much, that's what actually matters. I think it's cool they're working on speed improvements though, means my prototype-to-production cycle gets a bit smoother lol.
I'm thankful they included a compiled language for comparison, because most of the time when I see Python benchmarks, they measure against other versions of Python. But "fast python" is an oxymoron and 3.14 doesn't seem to really change that, which I feel most people expected given the language hasn't fundamentally changed.
This isn't a bad thing; I don't think Python has to be or should be the fastest language in the world. But it's interesting to me seeing Python getting adopted for a purpose it wasn't suited for (high performance AI computing). Given how slow it is, people seem to think there's a lot of room for performance improvements. Take this line for instance:
> The free-threading interpreter disables the global interpreter lock (GIL), a change that promises to unlock great speed gains in multi-threaded applications.
No, not really. I mean, yeah you might get some speed gains, but the chart shows us if you want "great" speed gains you have two options: 1) JIT compile which gets you an order of magnitude faster or 2) switch to a static compiled language which gets you two orders of magnitude faster.
But there doesn't seem to be a world where they can tinker with the GIL or optimize python such that you'll approach JIT or compiled perf. If perf is a top priority, Python is not the language for you. And this is important because if they change Python to be a language that's faster to execute, they'll probably have to shift it away from what people like about it -- that it's a dynamic, interpreted language good for prototyping and gluing systems together.
I've been writing Python professionally for a couple of decades, and there've only been 2-3 times where its performance actually mattered. When writing a Flask API, the timing usually looks like: process the request for .1ms, make a DB call for 300ms, generate a response for .1ms. Or writing some data science stuff, it might be like: load data from disk or network for 6 seconds, run Numpy on it for 3 hours, write it back out for 3 seconds.
You could rewrite that in Rust and it wouldn't be any faster. In fact, a huge chunk of the common CPU-expensive stuff is already a thin wrapper around C or Rust, etc. Yeah, it'd be really cool if Python itself were faster. I'd enjoy that! It'd be nice to unlock even more things that were practical to run directly in Python code instead of swapping in a native code backend to do the heavy lifting! And yet, in practice, its speed has almost never been an issue for me or my employers.
BTW, I usually do the Advent of Code in Python. Sometimes I've rewritten my solution in Rust or whatever just for comparison's sake. In almost all cases, choice of algorithm is vastly more important than choice of language, where you might have:
* Naive Python algorithm: 43 quadrillion years
* Optimal Python algorithm: 8 seconds
* Rust equivalent: 2 seconds
Faster's better, but the code pattern is a lot more important than the specific implementation.
> Or writing some data science stuff, it might be like: load data from disk or network for 6 seconds, run Numpy on it for 3 hours, write it back out for 3 seconds.
> You could rewrite that in Rust and it wouldn't be any faster.
I was asked to rewrite some NumPy image processing in C++, because NumPy worked fine for 1024px test images but balked when given 40 Mpx photos.
I cut the runtime by an order of magnitude for those large images, even before I added a bit of SIMD (just to handle one RGBX-float pixel at a time, nothing even remotely fancy).
The “NumPy has uber fast kernels that you can't beat” mentality leads people to use algorithms that do N passes over N intermediate buffers, that can all easily be replaced by a single C/C++/Rust (even Go!) loop over pixels.
Also reinforced by “you can never loop over pixels in Python - that's horribly slow!”
Fused expressions are possible using other libraries (numexpr is pretty good), but I agree that there's a reluctance to use things outside of NumPy.
Personally though I find it easier to just drop into C extensions at the point that NumPy becomes a limiting factor. They're so easy to do and it lets me keep the Python usability.
Same with opencv and even sometimes optimized matrix libraries in pure C++. These are all highly optimized. But often when you want to achieve something you have to chain stuff which quickly eats up a lot of cycles, just by copying stuff around and having multiple passes that the compiler is unable to fuse. You can often pretty easily beat that even if you are not an optimization god by manual loop fusion.
That's because you're doing web stuff. (I/O limited). So much of our computing experience has been degraded due to this mindset applied more broadly. Despite a steady improvement in hardware, my computing experiences have been stagnating and degraded in terms of latency, responsiveness etc.
I'm not going to even go into the comp chem simulations I've been running, or that about 1/3 the stuff I do is embedded.
I do still use python for web dev, partly because as you say, it's not CPU-bound, and partly because Python's Django framework is amazing. But I have switched to rust for everything else.
As a java backend dev mainly working on web services, I wanted to like python, but I have found it really hard to work on a large python project because the auto complete just does not work as well as something like java.
Maybe it is just due to not being as familiar with how to properly setup a python project, but every time I have had to do something in a django or fast api project it is a mess of missing types.
How do you handle that with modern python? Or is it just a limitation of the language itself?
Pycharm has been fine. Just disable the AI stuff and you get accurate completion. It even has completion for Django ORM stuff, which is heavily dynamic.
I won’t completely argue against that, and I’ve also adopted Rust for smaller or faster work. Still, I contend that a freaking enormous portion of computing workloads are IO bound to the point that even Python’s speed is Good Enough in an Amdahl’s Law kind of way.
I hear this a lot, but can you really say that you're consistently saturating a 1Gbps line for netcode or 6+ Gbps nvme for disk data? In my experience this doesn't really happen with code that isn't intentionally designed to minimize unnecessary work.
A lot of slow parsing tends to get grouped in with io, and this is where python can be most limiting.
I don't personally use Python directly for super IO intensive work. In my common use cases, that's nearly always waiting for a database to return or for a remote network API to respond. In my own work, I'm saturating neither disk nor network. My code often finds itself waiting for some other process to do that stuff on its behalf.
I've never understood this. Python cannot be optimized like C, C++ or Rust. It cannot do advanced functional things like OCaml, Haskell or Scala. It cannot run in browsers like TypeScript. It cannot do games programming like C# and it can't do crazy macro stuff like Clojure. I don't think it's even second best at those things.
And 300ms for a DB call is slow, in any case. We really shouldn't accept that as normal cost of doing business. 300ms is only acceptable if we are doing scrypt type of things.
In some cases. Are looking up a single indexed row in a small K-V table? Yep, slow. Are you generating reports on the last 6 years of sales, grouped by division within larger companies? That might be pretty fast.
I'm not sure why you'd even generalize that so overly broadly.
That's all true, so long as you completely ignore doing any processing on the data, like evaluating the rows and selectively appending some of them into a data structure, then sorting and serializing the results, let alone optimizing the query plan for the state of the system at that moment and deciding whether it makes more sense to hit the indexes or just slurp in the whole table given that N other queries are also executing right now, or mapping a series of IO queries to their exact address in the underlying disks, and performing the parity checks as you read the data off the RAID and combine it into a single, coherent stream of not-block-aligned tuples.
There's a metric boatload of abstractions between sending a UTF-8 query string over the packet-switched network and receiving back a list of results. 300ms suddenly starts looking like a smaller window than it originally appears.
There is nothing for us to take away in this discussion. So let me be the first to tune down: all I want to say is: don't take that 300ms as given, it sits in this uncomfortable region too short to be an async op and too long to be noticeable (anything between 50ms and 2s fits this bill). Most likely the query is doing something suspicious and would benefit the most to take a closer look at.
I was totally with you until that last sentence, then you lost me again.
Saying a DB query is too long by giving an arbitrary number is like saying a rope is too long. That’s solely dependent on what you’re doing with it. It’s literally impossible to say that X is too long unless you know what it’s used for.
People will always make bad decisions. For example, I'd also squint at a developer who wanted to write a new non-performance-critical network service in C. Or a performance-critical one, for that matter, unless there was some overwhelming reason they couldn't use Rust or even C++.
Advent of code is deliberately set up to be doable in Python. You can also imagine a useful problem which Rust takes 2 weeks to do, how long would it take in Python?
And my experience is this: you start using ORMs, and maybe you need to format a large table once in a while. Then your Python just dies. Bonus points if you're using async to service multiple clients with the same interpreter.
And you're now forced to spend time hunting down places for micro-optimizations. Or worse, you end up with a weird mix of Cython and Python that can only be compiled on the developer's machine.
Exactly, most Python devs neither need nor care about perf. Most applications don't even need perf, because whether it's .1 second or .001 seconds, the user is not going to notice.
But this current quest to make Python faster is precisely because the sluggishness is noticeable for the task it's being used for most at the moment. That 6 second difference you note between the Optimal Python and the optimal Rust is money on the table if it translates to higher hardware requirements or more server time. When everything is optimal and you could still be 4x faster, that's a tough pill to swallow if it means spending more $$$.
> most Python devs neither need nor care about perf.
You do understand that's a different but equivalent way of saying, "If you care about performance, then Python is not the language for you.", don't you?
Yes, I'm consistent in that. What I don't get is if that's the case, why is there such a focus on improving Python perf? At best they're getting marginal improvements on something that most Python devs claim they don't care about, and which they say is not important for Python as a language due to JIT, C interop, and so on.
I think perhaps their hope is that eventually Python can get to Go-level if not Rust-level performance if they keep up the optimizations. I do personally believe this to be possible. The motivating example is Julia, which is a high level language with low-level language's performance. After arriving there, developers will care.
I agree, I think that's probably the hope. It's interesting you bring up Julia here because I was just reading the post about the 1.12 release and this comment struck me:
Particularly this part is relevent to the Python discussion:
What is Julia's central conceit? It aims to solve "the two language" problem, i.e. the problem where prototyping or rapid development is done in a dynamic and interactive language like Python or MATLAB, and then moved for production to a faster and less flexible language like Rust or C++.
This is exactly what the speaker in the talk addresses. They are still using Julia for prototyping, but their production use of Julia was replaced with Rust. I've heard several more anecdotal stories of the exact same thing occurring. Here's another high profile instance of Julia not making it to production:
https://discourse.julialang.org/t/julia-used-to-prototype-wh...
Julia is failing at its core conceit.
So that's the question I have right now: what is Python supposed to be? Is it supposed to be the glue language that is easy to use and bind together a system made from other languages? Or is it trying to be what Julia is, a solution to the two language problem. Because it's not clear Julia itself has actually solved that.
The reason I bring this up is because there's a lot of "cake having/eating" floating around these types of conversations -- that's it's possible to be all the things, without a healthy discussion of what the tradeoffs are in going that direction, and what that would me mean for the people who are happy with the way things are. These little % gains are all Python is going to achieve without actually asking the developer to sacrifice their development process in some way.
I think Julia has largely not solved it because it is clunky to use for purposes other than scientific computing. Python can't be argued to be that, it's very nice for web development as well as scientific computing, the issue is just that for non-scientific computing use cases the perf. isn't great.
If you think Python is nice for scientific computing, you must have never tried Matlab. Python is pretty clunky in comparison in its syntax for scientific computing.
I used MATLAB for about 5 years, and then Mathematica, before switching to Python. I even had a job offer to work at MathWorks in Cambridge in about 2014!
LOL, python is plenty fast if you make sure it calls C or Rust behind the scenes. Typical of 'professional' python people. Something too slow? just drop into C. It surely sounds weird to everyone who complains about Python being slow and the response is on these lines.
But that’s the whole point of it. You have the option to get that speed when it really matters, but can use the easier dynamic features for the very, very many use cases where that’s appropriate.
This is an eternal conversation. Years ago, it was assembler programmers laughing at inefficient C code, and C programmers replying that sometimes they don’t need that level of speed and control.
You are correct. However it took about only about 10 years for C compilers to beat hand assembly (for the average programmer), thus proving the naysayers wrong.
Meanwhile Python is just as slow today as it was 30 years ago (on the same machine).
People really misconstrue the relationship between Python and C/C++ in these discussions.
Those libraries didn't spring out of thin air, nor were they ever existing.
People wanted to write and interface in python badly, that's why you have all these libraries with substantial code in another language yet research and development didn't just shift to that language.
TensorFlow is a C++ library with a python wrapping. Pytorch has supported C++ interface for some time now, yet virtually nobody actually uses tensorflow or pytorch in C++ for ML R&D.
If python was fast enough, most would be fine, probably even happy to ditch the C++ backends and have everything in python, but the reverse isn't true. The C++ interface exists, and no-one is using it. C++ is the replaceable part of this equation. Nobody would really care if Rust was used instead.
Even as a Fortran programmer, the majority of my flops come from BLAS, LAPACK, and those sort of libraries… putting me in the exact same boat as the Python programmers, really. The “professional” programmers in general don’t worry too much about tying their identities to language choices, I think.
This is a very common pattern in high level languages and has been a thing ever since Perl had first come onto the scene. The whole point was that you use more ergonomic, easier to iterate languages like Perl or Python for most of your logic and you drop down into C, C++, Zig, or Rust to write the performance sensitive portions of your code.
When compiled languages became popular again in the 2010s there was a renewed effort into ergonomic compiled languages to buck this trend (Scala, Kotlin, Go, Rust, and Zig all gained their popularity in this timeframe) but there's still a lot of code written with the two language pattern.
It's pretty simple. Nobody wants to do ML R&D in C++.
Tensorflow is a C++ library with python bindings. Pytorch has supported a C++ interface for some time now, yet virtually nobody uses C++ for ML R&D.
The relationship between Python and C/C++ is the inverse of the usual backend/wrapper cases. C++ is the replaceable part of the equation. It's a means to an end. It's just there because python isn't fast enough. Nobody would really care if some other high perf language took its place.
Speed is important, but C++ is even less suited for ML R&D.
I think readability is what made python a winner. I can quickly type down my idea like a pseudo code, I can easily skim through other people’s algos. In C++ even a simple algo with a 100 lines of pseudo code will balloon to thousands of lines in c++
I agree. Unless they make it like 10x faster it doesn't really change anything. It's still a language you only use if you absolutely don't care whatsoever about performance and can guarantee that you never will.
> Why not use a faster language in the first place?
Well for the obvious reason that there isn't really anything like a Jupyter notebook for C. I can interactively manipulate and display huge datasets in Python, and without having to buy a Matlab license. That's why Python took off in this area, really
I believe I heard that argument since before jupyter became popular.
Usually it was accompanied by saying that the time needed to write code is often more important than the time it takes to run, which is also often true.
All that said, jupyter is probably part of python's success, although I'm not the only one who actively avoids it and views it as a bit of a code smell.
I love Jupyter! What I don’t love is people writing large projects in a workbook, then asking how to run it as-is in production so they can continue to iterate on it in that form.
It’s not impossible, but neither is it the sort of thing you want to encourage.
I agree - Jupyter notebook is really the key feature Python has that makes it attractive for research/scientific computing. I would say the REPL too but until very recently it was extremely shoddy so I doubt many people did any serious work in it.
> I would say the REPL too but until very recently it was extremely shoddy
Can you elaborate? I've been using the Python REPL for more than two decades now, and I've never found it to be "shoddy". Indeed, in pretty much every Python project I work on, one of the first features I add for development is a standard way to load a REPL with all of the objects that the code works with set up properly, so I can inspect them.
Very obvious example - you can't paste code containing blank lines.
Another example: navigating this history is done line by line instead of using whole inputs.
It's just bare minimum effort - probably gnu readline piped directly into the interpreter or something.
I think they did improve it a lot very recently by importing the REPL from some other Python interpreter but I haven't upgraded to use that version yet so I don't know how good it is now.
> probably gnu readline piped directly into the interpreter or something
That is more or less how the REPL originally was implemented. I think there's more under the hood there now.
I still don't think what you describe qualifies as "shoddy". There are certainly limitations to the REPL, but "shoddy" to me implies that it's not really usable. I definitely would not agree with that.
The predecessors were really popular before it too - MATLAB in engineering in particular, Mathematica also popular in Physics and Maths departments particularly where the symbolic functionality was more useful. I used both in academia and IPython (later renamed Jupyter) was clearly a natural extension of those but open source, and without the baggage of MATLAB (only one function definition per file, etc.)
>>> you absolutely don't care whatsoever about performance and can guarantee that you never will.
Those are actually pretty good bets, better than most other technological and business assumptions made during projects. After all, a high percentage of projects, perhaps 95%, are either short term or fail outright.
And in my own case, anything I write that is in the 5% is certain to be rewritten from scratch by the coding team, in their preferred language.
Sure but you're still screwing yourself over on that 5% and for no real reason - there are plenty of languages that are just as good as Python (or better!) but aren't as hilariously slow.
And in my experience rewrites are astonishingly rare. That's why Dropbox uses Python and Facebook uses PHP.
A painful rewrite in another language is usually the only option in my experience.
If you're really lucky you have a small hot part of the code and can move just that to another language (a la Pandas, Pytorch, etc.). But that's usually only the case for numerical computing. Most Python code has its slowness distributed over the entire codebase.
It’s not painful, that’s the point. You have a working prototype now ready to port. (If the destination language is painful perhaps, but don’t do that.)
I recently ported a Python program to Rust and it took me much less time the second time, even though I write Rust more slowly per-line. Because I knew definitively what the program needed.
And if even that is too much optimizing the Python or adding Cython to a few hot loops is less difficult.
I have also ported a Python program to Rust (got a ~50x speedup) but this was a smallish program, under 10k lines of code.
Porting larger programs is rarely tractable. You can tell that because several large companies have decided that writing their own Python runtimes that are faster is less effort (although they all eventually gave up on that as far as I know).
Well, that's not true at all. Scientists care about performance, but it turns out that Python is really good for number crunching since it is really good for using very fast C libraries. I know people who use pandas to manipulate huge datasets from radar astronomy. Also, of course, it's used in machine learning. If Python was "only" used in situations where you don't care about performance, it would not be used in so many scenarios that definitely need high performance. Sure, it is not pure Python, but it's still Python being used, just used to orchestrate C libraries
If you’re actually building and shipping software as a business Python is great. The advantages of Python for a startup are many. Large pool of talent that can pickup the codebase on essentially day 1. Fairly easy to reason about, mature, code velocity, typically one and only one way to do things as opposed to JavaScript. There is way more to the story than raw performance.
It's not that great when you see that the majority of the Python code in businesses is a totally unmaintainable mess because it has incorrect, partial, or no type annotations, and is littered with serious errors that a most basic type checker would flag.
Probably people at some point were making same arguments about ASM and C. How many people though do ASM these days? Not arguing that for now it is relevant point, obviously Rust / C are way faster.
I doubt it. C is well within 2x of what you can achieve with hand written assembly in almost every case.
Furthermore writing large programs in pure assembly is not really feasible, but writing large programs in C++, Go, Rust, Java, C#, Typescript, etc. is totally feasible.
honestly if the performance of the python interpreter has a big impact on your application's performance and that's something you care about - you're already doing things very wrong
> And this is a bit disappointing. At least for this test, the JIT interpreter did not produce any significant performance gains, so much that I had to double and triple check that I used a correctly built interpreter with this feature enabled. I do not know much about the internals of the new JIT compiler, but I'm wondering if it cannot deal with this heavily recursive function.
FWIW one thing that is worth calling out here is that the initial goal for JIT right now in Python is getting it relatively stable, functional, and more or less getting the initial implementation out there. It's not surprising at all that it's not faster.
I say this because I think the teams working on free-threaded and JIT python maybe could have done a better job publicly setting expectations.
I mean, Guido had a 2021 Faster CPython presentation where they claimed "5x in 4 years (1.5x per year)"[0]. Developers have significantly walked back those expectations since then.
One important caveat to remember is that this is before a lot of the work on free-threaded python started in full force. A lot of cutting edge work had to be done to support this in the GC but this came with performance penalties. As a result, the trajectory of the Faster CPython effort changed quite a bit.
Didn't help Microsoft axed several folks on that team too...
tl;dr: Two orders of magnitude slower than Rust, so 2-3 orders slower than native. Python on a 2 GHz processor runs as fast as C on a 2-20 MHz processor.
True, Python could be better or worse than two orders of magnitude slower for your particular use case, but it's 70x slower for recursion and addition that it clearly hasn't special-cased. That's good to know.
Tangential, but I practically owe my life to this guy. He wrote the flask mega tutorial in what I followed religiously to launch my first website. Then right before launch, in the most critical part of my entire application; piping a fragged file in flask. He answered my stackoverflow question, I put his fix live, and the site went viral. Here's the link for posterity's sake https://stackoverflow.com/a/34391304/4180276
> flask
Off-topic, but I absolutely loathe new Flask logo. Old one[0] has this vintage, crafty feel. And the new one[1] looks like it was made by a starving high schooler experimenting with WordArt.
[0] - https://upload.wikimedia.org/wikipedia/commons/3/3c/Flask_lo...
[1] - https://flask.palletsprojects.com/en/stable/_images/flask-na...
I hope they go Full Cracker Barrel on this:
1. Original logo has country charm and soul.
2. Replaced with a modern soulless logo.
3. Customer outrage!
4. Company (or open source project) comes to its senses and returns to old logo.
https://media.nbcboston.com/2025/08/cracker-barrel-split.jpg
(n.b. The Cracker Barrel Rebellion is sometimes associated with MAGA. I am very far from that, but I have to respect when people of any political stripe get something right.)
the funny thing about the Cracker Barrel brouhaha is that the new one still looked like something you'd find on a pack of matches from a hotel bar in the 70s.
ah, the New Coke Gambit
Ah New Coke… Oddly I liked new coke better. My most 80s possession is a new coke can with max headroom on it.
They had both new and “classic” for a while co existing.
> Oddly I liked new coke better.
Fun fact: so did most focus groups and (I think?) blind taste tests when it was just presented as a new drink, but they tended to be horrified by the idea of it actually replacing classic Coke. The problem with that switch was mostly psychological / cultural, not chemical.
Also, Diet Coke, which remains quite popular, is still based on the New Coke formula except with the sweetener swapped out. The no-calorie version of classic Coke is Coke Zero. The Coca-Cola Company has been working to increase Coke Zero's popularity, and it is now much more popular than it used to be, but I think Diet Coke continues to be more popular than Coke Zero even now.
ahhh, Max Headroom. Classic memory
reference: https://en.wikipedia.org/wiki/Max_Headroom_signal_hijacking
The Cracker Barrel "controversy" seems to have largely been fueled by bots.
Any source for that?
https://www.nrn.com/casual-dining/cracker-barrel-s-logo-cont...
https://www.wsj.com/articles/bot-networks-are-helping-drag-c...
> According to research obtained by the Wall Street Journal from PeakMetrics, 44.5% of X posts about Cracker Barrel on Aug. 20 (when the new logo began to go viral), were posted by “bots or likely bots,” rising to 49% at the peak of the controversy.
I wonder how much this differs from the percentage for any trending topic on X?
The vast majority of Twitter posts are by bots, so 44.5% seems like a higher proportion of humans than usual. The Cracker Barrel thing was a hot topic amongst people I know for a good 48 hours.
It's more interesting to me how, without fail, a comment always pops in at the mention of Cracker Barrel to say "those were bots, fellow human."
If the "fueled by bots" comment wasn't here already I'd have written it.
Did anyone short Cracker Barrel stock? If not, I have a hard time seeing why bots would have any interest in investing the time/money. There also didn't seem to be any political clout being gained by the complaints.
More real-world is that I know tons of friends/relatives in the South and I don't know of even ONE that liked the redesign.
I recall reading somewhere about some investor who wanted to take control of cb who drove this, so less shorting and more opportunistic drive down the price to buy more shares at a lower price.
Yes. Sardar Biglari, who's an activist investor and the CEO and owner of Steak'n'Shake, has been pushing for more control over Cracker Barrel for several years. He amplified some of the backlash against Cracker Barrel.
https://fortune.com/2025/09/18/sardar-biglari-war-against-cr...
Rage baiting has value to certain groups.
Russia has gotten VERY good at amplifying any cultural differences or controversies in order to break US politics (and many other countries). If you hadn't noticed it has been VERY effective.
If you haven't noticed, there is no evidence of your claims.
There's no evidence to disprove them either.
Bots aren't necessarily aimed to promote "glorious motherland" directly, there are probably hundreds of people on a payroll searching for easy, popular targets to wreak havoc.
Paranoia. There is just as much evidence that the USA has influence operations in every country on the planet too.
You just have to read Reddit and YouTube and Twitter comments to see all the evidence you need.
Curious that you didn't include HN in that list.
Or the President.
I was unaware of the new logo… and I am just realizing for the first time after many many Flask apps… that the logo is not a chili pepper.
This logo is bad.. not even talking about the mark, the fonts are wtf. Uppercase 'F' shorter than the lower 'l' and 'k', the 'a' and the 'k' bad, even the lower bar on the 'f' angle is just... eww. And then the mark. I dont get any of this.
> the fonts are wtf. Uppercase 'F' shorter than the lower 'l' and 'k'
Just like in the old one. That is not strange in the slightest, it is a very common feature of typefaces that the ascenders of lower case letters overshoot the height of uppercase. That is one of the ways to distinguish an uppercase i from a lower case L.
> And then the mark. I dont get any of this.
They look to be following the Material Design logo trend that was in fashion a while ago. Following trends in logo design is never a good idea, it makes them look outdated soon.
Oof that a
I take it you’re not from Europe.
https://en.wikipedia.org/wiki/Drinking_horn
Using a chili pepper as a flask could work, though, but not necessarily recommended.
I was going to post the same thing; glad I searched for 'chili' and found your comment.
I feel dumb - I thought it was a chili pepper, too.
I didn't know that they have the new logo before reading your comment. Been 2 years since I last searched flask but yeah the old logo was vintage and I also preferred the old logo and the new logo feels mid/sucks.
The old logo is much better.
New logo is instantly forgettable. Would disappear as an app icon on a phone home screen, forever mistaken for a bank app.
Old logo is impossible to resize and present on any assets that aren't rectangular. Flask isn't a country podunk restaurant
> Old logo is impossible to resize and present on any assets that aren't rectangular.
Neither is the new one, because you have to be a madman to show this hideous thing anywhere.
> Old logo is impossible to resize and present on any assets that aren't rectangular. Flask isn't a country podunk restaurant
You're measuring it by irrelevant measures. This is like when all the terrible Western game devs criticised Elden Ring because it didn't have "good UX".
>Old logo is impossible to resize and present on any assets that aren't rectangular.
Who the fuck cares? That never hurt flask from becoming a well beloved widely adopted tidy framework.
And it's trivial to "resize and present" the old log on "assets that aren't rectangular"...
>Flask isn't a country podunk restaurant
Yeah, apparently by the new logo it's a generic mall fast food chain restaurant for people with zero taste
Haha, it is very similar! Spot-on.
Here's Sysco, generic mall fast food distributor:
https://www.youtube.com/watch?v=rXXQTzQXRFc
https://logos-world.net/wp-content/uploads/2024/01/Sysco-Log...
The old logo would seem at home on a shelf of classic O'Reilly books. :)
I think it should not have a logo, so it is left to interpretation.
Thinking about hand-rolled web services, I usually imagine either a stealth alcoholic's metal flask or a mad scientist's Erlenmeyer flask.
Yeah I yearn to go back to flask but the logo is giving me the ick.
Love the new one
What the…? I guess I’ve been reaching for FastAPI instead of flask these days because I had no idea this happened. Didn’t all the pallets projects have the old timey logos? I wonder what happened.
Oh God, that's not it.
The old logo is classic and bespoke. I could recall it from memory. It's impressionable.
The new one looks like an unfunded 2005-era dorm room startup. XmlHttpRequests for sheep herders.
No, it looks like a disney channel show in 2008 that had one season
Goodness gracious, that font in the new logo is the most hideous font I've seen in a very long time.
Huh. What most stands out to me about the logo, old and new, is that it clearly depicts a drinking horn instead of a flask.
https://medium.com/@tsecretdeveloper/why-logos-are-getting-b...
yikes, that is not a great logo. it has also lost its essence
In fact, when I saw the new logo, the first thing that came to my mind was Brigadier General Jack D. Ripper in Dr. Strangelove saying "I deny them my essence."
But, this seems to me the gestalt of modern design. Less less less. Until it is no more.
I also hate the new ones. And most of what modern design pumps out now days.
It’s hideous!
New logo looks like a device some tribes' men use to cover their member.
Whyyyyyyyy
The usual crap when either some "business" or some "designer" types come in
Wow, the new one is disgusting.
You have made my day, sir. :)
When I was in college I discovered the flask mega tutorial and fell in love with programming. Switched from an economics degree to software engineering and now work in the industry.
Thank you for the work you put in.
Also discovered flask in college but was a year away from finishing a marketing degree.
I'm now a SWE with just a marketing degree!
I am a SWE without any degrees. :D I dropped out to... study.
Yeah, our education system sucks that much.
https://www.youtube.com/watch?v=zDZFcDGpL4U
Economist here, started to learn to code as an elaborate way to procrastinate on my master's thesis after I've quit playing videogames.
Absolutely love seeing like a dozen people piling on Mr Grinberg to show gratitude for his work, and indeed the even little things he does to help uplift others in the field. It’s a good reminder that a small helpful contribution, or bit of teaching given at the right time, can be so valuable!
Please note the Buy Me Coffee button at the bottom of the post.
Amazing to see all of the people thanking you! Great to see that gratitude is still alive and well. You seemed to have touched a lot of lives through that mega tutorial! wow!
I also want to say thank you for the Flask Mega Tutorial.
When I started my first job as a Data Scientist, it helped me deploy my first model to production. Since then, I’ve focused much more on engineering.
You’ve truly started an amazing journey for me.
Thank you. :)
Whoa! You're here! Well, I think a lot of us owes you a debt of gratitude. Thank you for all you've done for the Python and Flask community.
I also want to chime in and say how you changed my life. I did the same Flask megatutorial and that led me to leaving helpdesk and becoming a support engineer. Years later, and I'm now in big tech. Thanks Miguel!
Thank you for the Flask Tutorial, it got me started in web development and down the line into systems development.
I came way late to the game, so went more the video side, so I have the same feelings about Pretty Printed, love his stuff.
But just now checking out the Mega Flask Tutorial, wow looks pretty awesome.
I learnt a lot from your numerous Flask blog posts over the years. Your blog is often better than the official Flask docs. Kudos to you, Miguel!
I also used your tutorial to get started with web development and helped me get my first job about 11 years ago. Thanks a lot!
I too started with your tutorial - thanks a million
I also learnt a lot from your tutorial of Flask. Thank you.
Rock on man
I also got started in webdev and built a few sitesdl from your tutorial. Thank you!
Nice story! My guess is that the site was https://yout.com/ given your profile. Does it still run Flask?
It's all grown up now. Runs on Django for the admin panel. Not that flask ever failed. Just became easier to manage the user base that way.
because of Django admin? any downsides/notable warnings for people considering Flask v Django? any migration guide that's helpful?
To limit the amount of languages we support I recently rewrote one of our backend services from Go (with SQLC) to Python. I hadn't worked with Python "web" for a while and started with Litestar and also their Advanced-Alchemy. Part of the reason was that their DTO's and dataclasses seemed like a good way to skip Pydantic. Anyway, once models became complext it wasn't easy to skip Pydantic and it also wasn't easy to deal with Advanced Alchemy. One afternoon I got so annoyed with it I rewrote everything with Django Ninja. It took me 4-5 hours that evening to recreate all the previous weeks stuff with Django because of how good the batteries included are.
I'm not sure I'd ever use any other web framework than Django going forward, and I'm not using half of it (including the admin). I think Litestar is great by the way, Django is just so easy to produce with.
Go with what you understand easier. No downsides to making an app in either, other than the logo.
Thanks for sharing this story. It goes to show how much of a difference being kind and helping a stranger can make.
Hope I'm able to do the same for someone one day :)
Same! This tutorial from 2012 was one of the first things I did in Python. Coming from PHP it was so refreshing. https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial...
For anyone else wondering whether to click to find what "fragged file" means: no, it's not about Quake and the linked page does not mention 'frag' at all. The question asks how to stream a file to the client in Flask as opposed to reading it all into memory at once and then sending it on. I figured as much (also because e.g. IP fragmentation) but first time I hear this alternative term for streaming
Same happened to me; I owe a career to having gone through his Mega Tutorial. Miguel if you're reading this, thank you from the bottom of my heart.
Same here with following the mega tutorial. Truly one of the goats.
Similar story here. Pleasant to work with too.
The accessibility of this material and also the broader python ecosystem is truly incredible. After reflecting on this recently, started finding ways to give back/donate/contribute.
such inspiring story!! And please bring back: https://www.microphonetest.com/?lang=en
one day of vibe coding
Yet another appreciation story for Miguel’s mega tutorial. In 2017 I used it to create our wedding site and learn a bit of web dev (my background is in data science). To motivate me to actually do it I used the strategy the fund the then occurring refactoring of the tutorial. I am still very fond and proud of that first time I actually went and funded some open source effort, it gives you back more than you might expect
We fixed the typo in the first sentence: ow -> owe. Hope that's okay!
Edit: corrected typo in "typo".
type -> typo
Incredible.
Did you throw any money his way?
Didn't know he had a patreon, just set it up so the first 100 people, since that's the max it allowed, can get a 1 year access to his discord https://www.patreon.com/miguelgrinberg/redeem/f/C28EB241BB
Didn’t even know you could do this, but what a cool way to do that — helping others learn from him while also materially supporting him.
Thank you so much!
That's awesome!
Thank you!
Awesome
Cool story, but was your life really at risk in that situation?
https://torrentfreak.com/tag/yout/
> Brazil Advances Criminal Prosecution of American Yout.com Operator
Touché! I see sibling comments assuming I was being sarcastic (without mandatory sarcasm tag!), but what I was really hoping for was more backstory like this. I guess it depends on how you read things in your head.
Not all statements should be interpreted literally.
You just took the wind right out of his sails
And took the shine off his shoes and stopped him in his tracks.
Luckily all the whooshing has refilled them.
I missed the part about a boat?
Turn the new Flask logo upside dowb, it’s a sail.
Please don’t make benchmarks with timing inside the loop creating a sum. Just time the loop and divide by the number. Stuff happens getting the time and the jitter can mess with results.
I'll plug timeit, from the standard library as a good approach.
https://docs.python.org/3/library/timeit.html
The real world benchmark is measuring it from invocation, both for cold launches and 'hot' (data cached from the last run).
Interestingly I might have only ever used the time (shell) builtin command. GNU's time measuring command prints a bunch of other performance stats as well.
I'm annoyed every time I have to write $(which time). But the stats given by -v are just so much more valuable from gnu-time.
Wouldn't it also work with "env time" if that's easier to type?
It would also work to just write 'time'
Quoting overrides aliases and builtins.
Python installation size over time:
Where are you getting these numbers?
Python 3.11 on Debian is around 21 MB installed size (python3.11-minimal + libpython3.11-minimal + libpython3.11-stdlib), not counting common shared dependencies like libc, ncurses, liblzma, libsqlite3, etc.
Looking at the embeddable distribution for Windows (32-bit), Python 3.11 is 17.5 MB unpacked, 3.13 is slightly smaller at 17.2 MB and 3.14 is 18.4 MB (and adds the _zstd and _remote_debugging modules).
This is the "standard" configure + make + make install, which includes libpython.a, header files, Python's own tests (python -m test), plus __pycache__, and debug symbols. Distros of course may split it up into multiple packages, split out debug symbols, etc.
See `docker run -it --rm -w /store ghcr.io/spack/all-pythons:2025-10-10`.
To be fair, the main contributors are tests and the static library.
Just looking at libpython.so
The static library is likely large because of `--with-optimizations` enabling LTO (so smaller shared libs, but larger static libs).With batteries included, growing should be a desired outcome.
considering I run 3.12 on a 256MB drive, I doubt
Every time I hear news about Python language itself, it sadden me that, in 2025, PyPy is still a separate distinct track from mainline Python.
That said, I wonder if GIL-less Python will one day enable GIL-less C FFI? That would be a big win that Python needs.
The biggest thing PyPy adds is JIT compilation. This is precisely what the project to add JIT to CPython is working on these days. It's still early days for the project, but by 3.15 there's a good chance we'll see some really great speedups in some cases.
It's worth noting that PyPy devs are in the loop, and their insights so far have been invaluable.
> That said, I wonder if GIL-less Python will one day enable GIL-less C FFI?
What do you mean exactly? C FFI has always been able to release the GIL manually.
> That said, I wonder if GIL-less Python will one day enable GIL-less C FFI? That would be a big win that Python needs.
I'm pretty sure that is what freethreading is today? That is why it can't be enabled by default AFAIK, as several C FFI libs haven't gone "GIL-less" yet.
Can you clarify the concern? Starting from C I've come to expect many dialects across many compiler implementations. It seems healthy and encourages experimentation. Is it not a sign of a health language ecosystem?
Pypy compatibility with cpython seems very minor in comparison https://pypy.org/compat.html
It's a culture thing. C culture is all about rolling your own bespoke solution, which encourages the formation of dialects. On the other hand, Python culture is all about "There should be one-- and preferably only one --obvious way to do it.": https://peps.python.org/pep-0020/#the-zen-of-python
I don't understand why C FFI is that popular.
The amount of time it takes spent to write all the cffi stuff is the same amount it takes to write an executable in C and call it from python.
The only time cffi is useful is if you want to have that code be dynamic, which is a very niche use case.
Could you go into more detail? How would you build e.g. numpy without FFI?
These days you could probably build a pretty performant numpy like using shared memory with Arrow format and IPC for control. Though it would be considerably more complex and not at all easier than FFI...
We need the FFI to share memory in-process with C functions?
Well, they added an experimental JIT so that is one step closer to PyPy? Though would assume the trajectory is build a new JIT vs. merge in PyPy, but hopefully people learned a lot from PyPy.
There is some information transfer happening. Antonio Cuni was at the latest Coython developer sprint and shared some insights from PyPy https://antocuni.eu/2025/09/24/tracing-jits-in-the-real-worl...
How do you see that changing?
Python introduce another breaking change than also randomly affects performance, making it worse for large classes of users?
Why would the Python organisers want to do that?
[flagged]
Guido stepped down over 7 years ago. How out of touch are you?
Who are you talking about? Python hasn't had a dictator for ages now.
He's right in everything else though.
For me the "criminal" thing is that Pypy exists on a shoestring and yet delivers the performance and multithreading that others gradually try to add to cpython.
It's problem is, IMO, compatibility. Long ago I wanted to run it on yocto but something or other didn't work. I think this problem is gradually disappearing but it could be solved far more rapidly with a bit of money and effort probably.
PyPy still has the GIL so the multithreading stuff is the same problem.
However, the JIT does make things much faster
What happened to the STM version of PyPy with no GIL?
I was soo excited when they announced this, but I've heard almost nothing since.
I hope it doesn't get stuck at 3.14, like TeX.
https://www.reddit.com/r/RedditDayOf/comments/7we430/donald_...
You hope it doesn't?
> [Donald Knuth] firmly believes that having an unchanged system that will produce the same output now and in the future is more important than introducing new features
This is such a breath of fresh air in a world where everything is considered obsolete after like 3 years. Our industry has a disease, an insatiable hunger for newness over completeness or correctness.
There's no reason we can't be writing code that lasts 100 years. Code is just math. Imagine having this attitude with math: "LOL loser you still use polynomials!? Weren't those invented like thousands of years ago? LOL dude get with the times, everyone uses Equately for their equations now. It was made by 3 interns at Facebook, so it's pretty much the new hotness." No, I don't think I will use "Equately", I think I'll stick to the tried-and-true idea that has been around for 3000 years.
Forget new versions of everything all the time. The people who can write code that doesn't need to change might be the only people who are really contributing to this industry.
> There's no reason we can't be writing code that lasts 100 years. Code is just math.
In theory, yes. In practice, no, because code is not just math, it's math written in a language with an implementation designed to target specific computing hardware, and computing hardware keeps changing. You could have the complete source code of software written 70 years ago, and at best you would need to write new code to emulate the hardware, and at worst you're SOL.
Software will only stop rotting when hardware stops changing, forever. Programs that refuse to update to take advantage of new hardware are killed by programs that do.
This is a total red herring, x86 has over 30 years of backwards compatability and the same goes for the basic peripherals.
The real reason for software churn isn't hardware churn, but hardware expansion. It's well known that software expands to use all available hardware resources (or even more, according to Wirth's law).
30 years ago, right before Windows 95 came out, Windows was a 16-bit OS and the modern versions of Windows no longer support 16-bit programs. PCIe came out only in 2003, and I don't know that PCIe slots can support PCI. SATA is also from 2003. Even USB originally came out in 1996, and the only pre-USB connector slot I have on my computer is a PS/2 port (which honestly surprises me). For monitor connections, VGA and DVI (1999!) have died off, and their successors (HDMI, DisplayPort) are only in the 2000's.
So pretty much none of the peripherals--including things like system memory and disk drives, do note--from a computer in 1995 can talk using any of the protocols a modern computer supports (save maybe a mouse and keyboard) and require compatibility adapters to connect, while also pretty much none of the software works without going through custom compatibility layers. And based on my experience trying to get a 31-year old Win16 application running on a modern computer, those compatibility layers have some issues.
PCIe is mostly backwards compatible with PCI, and bridge chips used to be quite common. ISA to PCI is harder, but not unheard of.
"SATA" stands for "serial ATA", and has the same basic command set as the PATA from 1984 - bridge chips were widely used. And it all uses SCSI, which is also what USB Mass Storage Devices use. Or if you're feeling fancy, there's a whole SCSI-to-NVMe translation standard as well.
HDMI is fully compatible with single-land DVI-D, you can find passive adapters for a few bucks.
There's one port you forgot to mention: ethernet! A brand-new 10Gbps NIC will happily talk with an ancient 10Mbps NIC.
It might look different, but the pc world is filled with ancient technology remnants, and you can build some absolutely cursed adapter stacks. If anything, the limiting factor is Windows driver support.
Slight caveat that a lot of Ethernet PHYs > 1G don't go down to 10 Mb, my some don't go to 100 Mb, and some are only the speed they want to be (though luckily that's not very common). There exist 6-speed PHYs (10,100,1000,2500,5000,10000) but that doesn't mean everything will happily talk
You're confusing quite a few things together.
The basic peripherals (keyboard and monitor) of today still present the same interface as they did back in the IBM PC era. Everything else is due to massive hardware expansion, not hardware churn.
How often do you update your drivers compare to your typical internet connected app? Software that handles the idiosyncrasies of the hardware (aka drivers) generally has a much longer lifespan than most other software; I don't see how you can reasonably say hardware breaking backwards compatibility is why software keeps changing.
Python programs do not care about SATA/PCI-E.
Try running software from 1995 on a brand new system and you'll find all sorts of fun reasons why it's more complicated than that.
I don’t think I can take that claim by itself as necessarily implying the cause is hardware. Consumer OSes were on the verge of getting protected memory at that time, as an example of where things were, so if I imagine “take an old application and try to run it” then I am immediately imagining software problems, and software bit rot is a well-known thing. If the claim is “try to run Windows 95 on bare metal”, then…well actually I installed win98 on a new PC about 10 years ago and it worked. When I try to imagine hardware changes since then that a kernel would have to worry about, I’m mostly coming up with PCI Express and some brave OEMs finally removing BIOS compatibility and leaving only UEFI. I’m not counting lack of drivers for modern hardware as “hardware still changes” because that feels like a natural consequence of having multiple vendors in the market, but maybe I could be convinced that is a fundamental change in and of itself…however even then, that state of things was extremely normalized by the 2000s.
Drivers make up a tiny portion of the software on our computer by any measure (memory or compute time) and they're far longer lasting than your average GUI app.
On the other hand, the main reason why Y2K happened was because a lot of major orgs would rather emulate software from the 60s forever than rewrite it. I'm talking like ancient IBM mainframe stuff, running on potentially multiple layers of emulation and virtualization.
We rewrite stuff for lots of reasons, but virtualization makes it easy enough to take our platforms with us even as hardware changes.
Pretty sure if I downloaded and compiled Tcl/Tk 7.6.x source code on a modern Linux box, it would run my Tcl/Tk 7.6.x "system monitor" code from 1995 or 1996 just fine.
Do you have any examples that aren't because of the OS (as in, not trying to run a 90's game on Windows 11) or specialized hardware (like an old Voodoo GPU or something)?
If you restrict yourself to programs that don't need an OS or hardware, you're going to be looking at a pretty small set of programs.
I don't, but I do restrict that you run it on the same OS as it was designed for.
The whole point is that everything changes around software. Drivers, CPUs, GPUs, web browsers, OSs, common libraries, etc. Everything changes.
It doesn't matter if x86 is backwards compatible if everything else has changed.
No code can last 100 years in any environment with change. That's the point.
x86 doesn't have magical backwards compatibility powers.
The amazing backwards compatibility of Windows is purely due to the sheer continuous effort of Microsoft.
> x86 doesn't have magical backwards compatibility powers.
I never said it did; other ISAs have similar if not longer periods of backwards compatability (IBM's Z systems architecture is backwards compatible with the System/360 released in 1964).
> The amazing backwards compatibility of Windows is purely due to the sheer continuous effort of Microsoft.
I never mentioned Windows but it's ridiculous to imply its backwards compatability is all on Microsoft. Show me a single example of a backwards breaking change in x86 that Windows has to compensate for to maintain backwards compatability.
>I never mentioned Windows but it's ridiculous to imply its backwards compatability is all on Microsoft.
I never said that. Windows was just an easy example.
>Show me a single example of a backwards breaking change in x86 that Windows has to compensate for to maintain backwards compatability.
- The shift from 16-bit to 32-bit protected mode with the Intel 80386 processor that fundamentally altered how the processor managed memory.
- Intel 80286 introduced a 24-bit address bus to support more memory, but this broke the address wraparound behavior of the 8086.
- The shift to x86-64 that Microsoft had to compensate with emulation and WOW64
Any many more. That you think otherwise just shows all the effort that has been done.
> The shift from 16-bit to 32-bit protected mode with the Intel 80386 processor that fundamentally altered how the processor managed memory.
I said x86 has "over 30 years of backwards compatibility". The 80386 was released in 1985, 40 years ago :)
> Intel 80286 introduced a 24-bit address bus to support more memory, but this broke the address wraparound behavior of the 8086.
This is the only breaking change in x86 that I'm aware of and it's a rather light one as it only affected programs relying on an exactly 2^16 memory space. And, again, that was over 40 years ago!
> The shift to x86-64 that Microsoft had to compensate with emulation and WOW64
No, I don't think so. A x86-64 CPU starts in 32 bit mode and then has to enter 64 bit mode (I'd know, I spent many weekends getting that transition right for my toy OS). This 32 bit mode is absolutely backwards compatible AFAIK.
WOW64 is merely a part of Microsoft's OS design to allow 32 bit programs to do syscalls to a 64 bit kernel, as I understand it.
The bare minimum cost of software churn is the effort of one human being, which is far less than hardware churn (multiple layers of costly design and manufacturing). As a result, we see hardware change gradually over the years, while software projects can arbitrarily deprecate, change, or remove anything at a whim. The dizzying number of JS frameworks, the replacement of X with Wayland or init with systemd, removal of python stdlib modules, etc. etc. have nothing to do with new additions to the x86 instruction set.
TeX is written in a literate programming style which is more akin to a math textbook than ordinary computer code, except with code blocks instead of equations. The actual programming language in the code blocks and the OS it runs on matters a lot less than in usual code where at best you get a few sparse comments. Avoiding bit rot in such a program is a very manageable task. In fact, iirc the code blocks which end up getting compiled and executed for TeX have been ported from Pascal to C at some point without introducing any new bugs.
The C version of TeX is also terrible code in the modern day (arbitrary limits, horrible error handling, horrible macro language, no real Unicode support, etc. etc), hence LuaTeX (et al.) and Typst and such.
The backward-compat story is also oversold because, yes, baseline TeX is backward compatible, but I bet <0.1% of "TeX" document don't use some form of LaTeX and use any number of packages... which sometimes break at which point the stability of base TeX doesn't matter for actual users. It certainly helps for LaTeX package maintainers, but that doesn't matter to users.
Don't get me wrong, TeX was absolutely revolutionary and has been used for an insane amount of scientific publishing, but... it's not great code (for modern requirements) by any stretch.
Given how mature emulation is now why couldn't that just continue to be possible into the future?
Each new layer of emulation is new code that needs to be written that wasn't required when the original program in question was written. It's a great approach for software preservation, but the fact that it's necessary shows why the approach of "if it ain't broke, don't fix it" doesn't work. The context of computing is changing around us at all times, and hardware has a finite lifespan.
Eh. Emulators are often tiny in comparison to the programs they emulate. Especially when performance isn't so much of a concern - like when you're emulating software written for computers from many decades ago. A good emulator can also emulate a huge range of software. Just look at programs like dosbox and the like. Or Apple's great work with Rosetta and Rosetta2 - which are both complex, but much less complex than all the software they supported. Software like Chrome, Adobe Photoshop and the Microsoft office suite.
Arguably modern operating systems are all sort of virtual machine emulators too. They emulate a virtual computer which has special instructions to open files, allocate memory, talk to the keyboard, make TCP connections, create threads and so on. This computer doesn't actually exist - its just "emulated" by the many services provided by modern operating systems. Thats why any windows program can run on any other windows computer, despite the hardware being totally different.
Or get an IBM 360 and have support for the next two thousand years, which is the choice our parents made.
This is possible, and ubiquitous. Your terminal runs on an emulator of an emulator of a teletype.
This is correct when it comes to bare metal execution.
You can always run code from any time with emulation, which gives the “math” the inputs it was made to handle.
Here’s a site with a ton of emulators that run in browser. You can accurately emulate some truly ancient stuff.
https://www.pcjs.org/
Are you by chance a Common Lisp developer? If not, you may like it (well, judging only by your praise of stability).
Completely sidestepping any debate about the language design, ease of use, quality of the standard library, size of community, etc... one of its strengths these days is that standard code basically remains functional "indefinitely", since the standard is effectively frozen. Of course, this requires implementation support, but there are lots of actively maintained and even newer options popping up.
And because extensibility is baked into the standard, the language (or its usage) can "evolve" through libraries in a backwards compatible way, at least a little more so than many other languages (e.g. syntax and object system extension; notable example: Coalton).
Of course there are caveats (like true, performant async programming) and it seems to be a fairly polarizing language in both directions; "best thing since sliced bread!" and "how massively overrated and annoying to use!". But it seems to fit your description decently at least among the software I use or know of.
I respect and understand the appeal of LISP. It is a great example of code not having to change all the time. I personally haven't had a compelling reason to use it (post college), but I'm glad I learned it and I wouldn't be averse to taking a job that required it.
While writing "timeless" code is certainly an ideal of mine, it also competes with the ideals of writing useful code that does useful things for my employer or the goals of my hobby project, and I'm not sure "getting actual useful things done" is necessarily LISP's strong suit, although I'm sure I'm ruffling feathers by saying so. I like more modern programming languages for other reasons, but their propensity to make backward-incompatible changes is definitely a point of frustration for me. Languages improving in backward-compatible ways is generally a good thing; your code can still be relatively "timeless" in such an environment. Some languages walk this line better than others.
I think, the "useful" part is more covered by libraries than everything else, and the stability and flexibility of the core language certainly helps with that. Common Lisp is just not very popular (as every lisp) and does not have a very big ecosystem, that's it.
Another point for stability is about how much a runtime can achieve if it is constantly improved over decades. Look where SBCL, a low-headcount project, is these days.
We should be very vigilant and ask for every "innovation" whether it is truly one. I think it is fair to assume for every person working in this industry for decades that the opinion would be that most innovations are just fads, hype and resume-driven development - the rest could be as well implemented as a library on top of something existing. The most progress we've had was in tooling (rust, go) which does not require language changes per se.
I think, the frustrating part about modern stacks is not the overwhelming amount of novelty, it is just that it feels like useless churn and the solutions are still as mediocre or even worse that what we've had before.
Stability is for sure a very seducing trait. Also I can totally understand the fatigue of the chase for the next almost already obsolete new stuff.
>There's no reason we can't be writing code that lasts 100 years.
There are many reason this is most likely not going to happen. Code despite best effort to achieve separation of concern (in the best case) is a highly contextual piece of work. Even with a simple program with no external library, there is a full compiler/interpreter ecosystem that forms a huge dependency. And hardware platforms they abstract from are also moving target. Change is the only constant, as we say.
>Imagine having this attitude with math: "LOL loser you still use polynomials!? Weren't those invented like thousands of years ago?
Well, that might surprise you, but no, they weren't. At least, they were not dealt with as they are thought and understood today in their contemporary most common presentation. When Babylonians (c. 2000 BCE) solved quadratic equation, they didn't have anything near Descartes algebraic notation connected to geometry, and there is a long series evolution in between, and still to this days.
Mathematicians actually do make a lot of fancy innovative things all the time. Some fundamentals stay stable over millennia, yes. But also some problem stay unsolved for millennia until some outrageous move is done out of the standard.
Don't know about 100 years, but old static web page from lat 90's with js on wayback machine still works. There might be something to this static html css to archive content maybe even little programs.
Yes, and we only need a browser to achieve that, the kind of piece of software well known to be small, light and having only sporadic changes introduced into them. :D
That's actually a good moment to wander about what an amazing they are, really.
To be fair, if math did have version numbers, we could abandon a lot of hideous notational cruft / symbol overloading, and use tau instead of pi. Math notation is arguably considerably worse than perl -- can you imagine if perl practically required a convention of single-letter variable names everywhere? What modern language designer would make it so placing two variable names right next to each other denotes multiplication? Sheer insanity.
Consider how vastly more accessible programming has become from 1950 until the present. Imagine if math had undergone a similar transition.
Math personally "clicked" to me when I started to use Python and R for mathematical operations instead of the conventional arcane notation. I did make me wonder why we insist on forcing kids and young adults to struggle through particularly counter-intuitive ways to express mathematical concepts just because of historical baggage, and I am glad to hear now that I am not the only one who thinks this way.
What in the Hacker News in this comment?
Mathematical notation evolved to its modern state over centuries. It's optimized heavily for its purpose. Version numbers? You're being facetious, right?
>evolved
Yes, it evolved. It wasn't designed.
>Version numbers?
Without version numbers, it has to be backwards-compatible, making it difficult to remove cruft. What would programming be like if all the code you wrote needed to work as IBM mainframe assembly?
Tau is a good case study. Everyone seems to agree tau is better than pi. How much adoption has it seen? Is this what "heavy optimization" looks like?
It took hundreds of years for Arabic numerals to replace Roman numerals in Europe. A medieval mathematician could have truthfully said: "We've been using Roman numerals for hundreds of years; they work fine." That would've been stockholm syndrome. I get the same sense from your comment. Take a deep breath and watch this video: https://www.youtube.com/watch?v=KgzQuE1pR1w
>You're being facetious, right?
I'm being provocative. Not facetious. "Strong opinions, weakly held."
> Without version numbers, it has to be backwards-compatible
If there’s one thing that mathematical notation is NOT, it’s backwards compatible. Fields happily reuse symbols from other fields with slightly or even completely different meanings.
https://en.wikipedia.org/wiki/Glossary_of_mathematical_symbo... has lots of examples, for example
÷ (division sign)
Widely used for denoting division in Anglophone countries, it is no longer in common use in mathematics and its use is "not recommended". In some countries, it can indicate subtraction.
~ (tilde)
1. Between two numbers, either it is used instead of ≈ to mean "approximatively equal", or it means "has the same order of magnitude as".
2. Denotes the asymptotic equivalence of two functions or sequences.
3. Often used for denoting other types of similarity, for example, matrix similarity or similarity of geometric shapes.
4. Standard notation for an equivalence relation.
5. In probability and statistics, may specify the probability distribution of a random variable. For example, X∼N(0,1) means that the distribution of the random variable X is standard normal.
6. Notation for proportionality. See also ∝ for a less ambiguous symbol.
Individual mathematicians even are known to have broken backwards compatibility. https://en.wikipedia.org/wiki/History_of_mathematical_notati...
* Euler used i to represent the square root of negative one (√-1) although he earlier used it as an infinite number*
Even simple definitions have changed over time, for example:
- how numbers are written
- is zero a number?
- is one a number?
- is one a prime number?
> Fields happily reuse symbols from other fields with slightly or even completely different meanings.
Symbol reuse doesn't imply a break in backwards compatibility. As you suggest with "other fields", context allows determining how the symbols are used. It is quite common in all types of languages to reuse symbols for different purposes, relying on context to identify what purpose is in force.
Backwards incompatibility tells that something from the past can no longer be used with modern methods. Mathematical notation from long ago doesn't much look like what we're familiar with today, but we can still make use of it. It wasn't rendered inoperable by modern notation.
If the compiler forbade syntactic ambiguity from implicit multiplication and had a sensible LSP allowing it to be rendered nicely, I don't think that'd be such a bad thing. Depending on the task at hand you might prefer composition or some other operation, but when reducing character count allows the pattern recognition part of our brain to see the actual structure at hand instead of wading through character soup it makes understanding code much easier.
Yep, this explains why the APL programming language was so ridiculously successful.
> There's no reason we can't be writing code that lasts 100 years. Code is just math.
The weather forecast is also “just math”, yet yesterday’s won’t be terribly useful next April.
> There's no reason we can't be writing code that lasts 100 years. Code is just math. Imagine having this attitude with math: "LOL loser you still use polynomials!? Weren't those invented like thousands of years ago? LOL dude get with the times, everyone uses Equately for their equations now. It was made by 3 interns at Facebook, so it's pretty much the new hotness." No, I don't think I will use "Equately", I think I'll stick to the tried-and-true idea that has been around for 3000 years.
Not sure this is the best example. Mathematical notation evolved a lot in the last thousand years. We're not using roman numerals anymore, and the invention of 0 or of the equal sign were incredible new features.
I agree somewhat with your sentiment and have some nostalgia for a time when software could be finished, but the comment you're replying to was making a joke that I think you may have missed.
> There's no reason we can't be writing code that lasts 100 years. Code is just math
Math is continually updated, clarified and rewritten. 100 years ago was before the Bourbaki group.
Mathematical notion has changed over the years. Is Diophantus' original system of polynomials that legible to modern mathematicians? (Even if you ignore the literally being written in ancient greek part.)
> an insatiable hunger for newness over completeness or correctness.
I understand some of your frustration, but often the newness is in response to a need for completeness or correctness. "As we've explored how to use the system, we've found some parts were missing/bad and would be better with [new thing]". That's certainly what's happening with Python.
It's like the Incompleteness Theorem, but applied to software systems.
It takes a strong will to say "no, the system is Done, warts and missing pieces and all. Deal With It". Everyone who's had to deal with TeX at any serious level can point to the downsides of that.
Worth noting that few people use the TeX executable as specified by Knuth. Even putting aside the shift to pdf instead of dvi output, LaTeX requires an extended TeX executable with features not part of the Knuth specification from 1988.
Btw, equations and polynomials while conceptually are old, our contemporary notation is much younger, dating to the 16th century, and many aspects of mathematical notation are younger still.
This philosophy may have its place in some communities, but Python is definitely not one of them.
Even C/C++ introduces breaking changes from time to time (after decades of deprecation though).
There’s no practical reason why Python should commit to a 100+ year code stability, as all that comes at a price.
Having said that, Python 2 -> 3 is a textbook example of how not to do these things.
Python is pretty much on the other extreme as 3.x → 3.y should be expected to break things, there's no "compability mode" to not break things, and the reasons for the breakage can be purely aestetic bikeshedding
C in contrast generally versions the breaking changes in the standard, and you can keep targeting an older standard on a newer compiler if you need to, and many do
While i think Latex is fantastic, i think there is plenty of low hanging fruit to improve upon it... the ergonomics of the language and its macros aren't great. If nothing else there should be a better investment in tooling and ecosystem.
Some stuff like LAPACK and BLAS fit your bill. They are math libraries written decades ago and still in use.
LAPACK and OpenBLAS regularly release new versions
Kinda related question, but is code really just a math? Is it possible to express things like user input, timings, inteerupts, error handling, etc. as math?
I would slightly sort of disagree that code is just math when you really boil it down, however, if you take a simple task, say, printing hello world to the output, you could actually break that down into a mathematical process. You can mathematically say at time T value of O will be the value of index N of input X, so over a period of time you eventually get "hello world" as the final output
Howeveeerrr.. its not quite math when you break down to the electronics level, unless you go really wild (wild meaning physics math). take a breakdown of python to assembly to binary that flips the transistors doing the thing. You can mathematically define that each transistor will be Y when that value of O is X(N); btw sorry i can't think of a better way to define such a thing from mobile here. And go further by defining voltages to be applied, when and where, all mathematically.
In reality its done in sections. At the electronic level math defines your frequency, voltage levels, timing, etc; at the assembly level, math defines what comparisons of values to be made or what address to shift a value to and how to determine your output; lastly your interpreter determines what assembly to use based on the operations you give it, and based on those assembly operations, ex an "if A == B then C" statement in code is actually a binary comparator that checks if the value at address A is the same as the value at address B.
You can get through a whole stack with math, but much of it has been abstracted away into easy building blocks that don't require solving a huge math equation in order to actually display something.
You can even find mathematical data among datasheets for electronic components. They say (for example) over period T you cant exceed V volts or W watts, or to trigger a high value you need voltage V for period T but it cannot exceed current I. You can define all of your components and operations as an equation, but i dont think its really done anymore as a practice, the complexity level of doing so (as someone not building a cpu or any ic) isnt useful unless youre working on a physics paper or quantum computing, etc etc
Isn’t it possible to express anything as math? With sufficient effort that is.
If you look at old math treatises from important historical people you'll notice that they use very different notation from the one you're used to. Commonly concepts are also different, because those we use are derived over centuries from material produced without them and in a context where it was traditional to use other concepts to suss out conclusions.
But you have a point, and it's not just "our industry", it's society at large that has abandoned the old in favour of incessant forgetfulness and distaste for tradition and history. I'm by no means a nostalgic but I still mourn the harsh disjoint between contemporary human discourse and historical. Some nerds still read Homer and Cicero and Goethe and Ovid and so on but if you use a trope from any of those that would have been easily recognisable as such by europeans for much of the last millenium you can be quite sure that it won't generally be recognised today.
This also means that a lot of early and mid-modern literature is partially unavailable to contemporary people, because it was traditional to implicitly use much older motifs and riff on them when writing novels and making arguments, and unless you're aware of that older material you'll miss out on it. For e.g. Don Quixote most would need an annotated version which points out and makes explicit all the references and riffing, basically destroying the jokes by explaining them upfront.
My C++ from 2005 still compiles! (I used boost 1.32)
Most of my python from that era also works (python 3.1)
The problem is not really the language syntax, but how libraries change a lot.
Except uh, nobody uses infinitesimals for derivatives anymore, they all use limits now. There's still some cruft left over from the infinitesimal era, like this dx and dy business, but that's just a backwards compatibility layer.
Anyhoo, remarks like this are why the real ones use Typst now. TeX and family are stagnant, difficult to use, difficult to integrate into modern workflows, and not written in Rust.
> the real ones use Typst now
Are you intentionally leaning into the exact caricature I'm referring to? "Real programmers only use Typstly, because it's the newest!". The website title for Typst when I Googled it literally says "The new foundation for documents". Its entire appeal is that it's new? Thank you for giving me such a perfect example of the symptom I'm talking about.
> TeX and family are stagnant, difficult to use, difficult to integrate into modern workflows, and not written in Rust.
You've listed two real issues (difficult to use, difficult to integrate), and two rooted firmly in recency bias (stagnant, not written in Rust). If you can find a typesetting library that is demonstrably better in the ways you care about, great! That is not an argument that TeX itself should change. Healthy competition is great! Addiction to change and newness is not.
> nobody uses infinitesimals for derivatives anymore, they all use limits now
My point is not that math never changes -- it should, and does. However, math does not simply rot over time, like code seems to (or at least we simply assume it does). Math does not age out. If a math technique becomes obsolete, it's only ever because it was replaced with something better. More often, it forks into multiple different techniques that are useful for different purposes. This is all wonderful, and we can celebrate when this happens in software engineering too.
I also think your example is a bit more about math pedagogy than research -- infinitesimals are absolutely used all the time in math research (see Nonstandard Analysis), but it's true that Calculus 1 courses have moved toward placing limits as the central idea.
>My point is not that math never changes -- it should, and does. However, math does not simply rot over time, like code seems to (or at least we simply assume it does). Math does not age out.
Just in the same sense that CS does not age out. Most concepts stick, but I'm pretty sure you didn't go through Στοιχεία (The Elements) in its original version. I'm also pretty confident that most people out there that use many of the notion it holds and helped to spread never threw their eyes over a single copy of it in their native language.
> I'm pretty sure you didn't go through Στοιχεία (The Elements) in its original version
This is like saying "you haven't read the source code of the first version of Linux". The only reason to do that would be for historical interest. There is still something timeless about it, and I absolutely did learn Euclid's postulates which he laid down in those books, all 5 of which are still foundational to most geometry calculations in the world today, and 4 of which are foundational to even non-Euclidean geometry. The Elements is a perfect example of math that has remained relevant and useful for thousands of years.
So that's it. Just because new languages and framework are rising and fading away, it doesn't mean there is nothing kept all along the way. It just that specific implementation is not the thing that people deem the most important to preserve over time.
> The website title for Typst when I Googled it literally says "The new foundation for documents". Its entire appeal is that it's new?
It might not be the best tagline, but that is most certainly not the entire appeal of Typst. It is a huge improvement over Latex in many ways.
Even if Typst was going to replace TeX everywhere right now, about half a century would still be a respectable lifespan for a software project.
> nobody uses infinitesimals for derivatives anymore
All auto-differentiation libraries today are built off of infinitesimals via Dual numbers. Literally state of the art.
It did previously get stuck on 2.7, it might have an affinity to mathematical constants.
Highly unlikely - Python 3.15 is already under active development: https://docs.python.org/3.15/whatsnew/3.15.html
Since π is a constant, I am afraid :)
LMAO that actually fits really well given all the πthon jokes
I don't know how realistic only using a benchmark that only uses tight loops and integer operations. Something with hashmaps and strings more realistically represents everyday cpu code in python; most python users offload numeric code to external calls.
There is no "realistic" benchmark, all benchmarks are designed to measure in a specific way. I explain what my goals were in the article, in case you are curious and want to read it.
Run a django app and throw traffic at it wouldnt be bad.
I agree with you, this is not an in depth look, could have been much more rigorous.
But then I think in some ways it's a much more accurate depiction of my use case. I mainly write monte-carlo simulations or simple scientific calculations for a diverse set of problems every day. And I'm not going to write a fast algorithm or use an unfamiliar library for a one-off simulation, even if the sim is going to take 10 minutes to run (yes I use scipy and numpy, but often those aren't the bottlenecks). This is for the sake of simplicity as I might iterate over the assumptions a few times, and optimized algorithms or library impls are not as trivial to work on or modify on the go. My code often looks super ugly, and is as laughably unoptimized as the bubble sort or fib(40) examples (tail calls and nested for loops). And then if I really need the speed I will take my time to write some clean cpp with zmq or pybind or numba.
Sounds like Julia would be a perfect fit for your use case.
Try Numby, Mojo, or a Python to C/C++ compiler.
It's still interesting though. If the most basic thing isn't notably faster, it makes it pretty likely the more complex things aren't either.
If your actual load is 1% python and 99% offloaded, the effect of a faster python might not mater a lot to you, but to measure python you kinda have to look at python
Or have it run some super common use case like a FastAPI endpoint or a numpy calculation. Yes, they are not all python, but it's what most people use Python for.
FastAPI is a web framework, which by definition is (or should be!) an I/O bound process. My benchmark evaluates CPU, so it's a different thing. There are a ton of web framework benchmarks out there if you are interested in FastAPI and other frameworks.
And numpy is a) written in C, not Python, and b) is not part of Python, so it hasn't changed when 3.14 was released. The goal was to evaluate the Python 3.14 interpreter. Not to say that it wouldn't be interesting to evaluate the performance of other things as well, but that is not what I set out to do here.
Numpy is partly written in C but includes a lot of Python code. If you include scipy or scikit learn or pandas, most of the code is python calling primitive numpy C operations. I'd expect that many semi-complex data science programs to benefit from improvement in the python interpreter, especially if they weren't written in super tight numpy code.
That's the thing with Python: A lot of things should be bound by all kinds of limitations, but are in practice often limited by the Python interpreter if not done carefully.
Fundamentally for example, if you're doing some operations on numpy arrays like: c = a + b * c, interpreted numpy will be slower than compiled numba or C++ just because an eager interpreter will never fuse those operations into an FMA.
Really pleasing to see how smooth the non-GIL transition was. If you think about 2->3 python this was positively glorious.
And that it gets into spitting range of standard so fast is really promising too. That hopefully means the part not compatible with it get flushed out soon-ish
AFAIU GIL is still the default, and no-GIL is a build option, you can't select it at runtime.
The big issue is what about all those C extension modules, some of them might require a lot of changes to work properly in a no-GIL world.
> Free-threaded builds of CPython support optionally running with the GIL enabled at runtime using the environment variable `PYTHON_GIL` or the command-line option `-X gil`.
https://docs.python.org/3/howto/free-threading-python.html
it still has GIL, likely a few more versions until we get rid of it
More than 300 comments here and still no convincing answer. Why the community wastes time on trying to make CPython faster when there is pypy which is already much faster? I understand pypy lacks libraries and feature parity with up to date CPython. But… can’t everyone refocus the efforts and just move to pypy to add all the missing bits and then just continue with pypy as the “official python”? Are there any serious technical reasons not to do it?
> Are there any serious technical reasons not to do it?
Yes.
First is startup time. REPL cycle being fast is a big advantage for development. From a business perspective, dev time is more expensive then compute time by orders of magnitude. Every time you make a change, you have to recompile the program. Meanwhile with regular python, you can literally develop during execution.
Second is compatibility. Numpy and pytorch are ever evolving, and those are written a C extensions.
Third is LLMs. If you really want speed, Gemma27bqat that runs on a single 3090 can translate python codebase into C/C++ pretty easily. No need to have any additional execution layer. My friend at Amazon pretty much writes Java code this way - prototypes a bunch of stuff in Python, and then has an LLM write the java code thats compatible with existing intra-amazon java templates.
I really hope I'll never need to touch code written by people who code in python and throws it at a plausible randomiser to get java or C
If you for some reason do this, please keep the python around so I can at least look at whatever the human was aiming at. It's probably also wrong as they picked this workflow, but there's a chance it has something useful
LLMs are there to get the meat of the software in. Fine tuning it is easy when you already have all the syntax written for you. With enough prompting on how you want the code laid out, the modern models do a really good job of getting it right with very minor things you have to tweak.
I get the "old man yells at cloud" vibes from your comment. Who cares how he got the result? I thought our job is to create working software. If this flow works for him and creates code that meets company standards, then more power to him.
However, if the output quality is crap, then well, maybe his creativity should not be rewarded. I've seem hefty amount of Map<Object, Object> in Java, written primarily by JS developers.
"create working software" is usually just a tiny bit of the job. That software then exists and needs to be extended and maintained.
If the result is great and maintainable code, great. I imagine it won't be, as no one has actually understood it even once.
As an old man myself, I am quite sure the other old man has a good reason to yell at this particular cloud. Software is tremendously complex. It is one thing to write it, it is another to amend the thousands and thousands of bugs that inevitably follow, and implement the even bigger amount of adjustments and improvements successful software requires. The latter is the bane of any kind of code generation, whether is RAD, no-code, low-code or LLM ported codebases.
Any kind of code generation that proves incredibly productivity in the writing of software is kind of like saying you have a lot of money by maxing out your creditcard. Maybe you can pay it back, maybe you can't. The fact that there is no mention of future debt is exactly the kind of thing that old men get suspicious about.
I'm not saying the old men are correct. I'm just pointing out the reason for the yelling.
Repl I get it. Possibly valid point. Yet I guess same issue are valid to node.js which seems much faster in many cases and still has valid dev experience.
C compatibility / extension compatibility - nope. First, it is an issue of limited resources. Add more devs to pypy team and compatibility bugs gets fixed. Second, aren’t people writing C extensions due to python being slow? Make python fast - as pypy - and for some cases native code won’t be that crucial.
So I don’t see a real issue with pypy that could not be solved by simply moving all the dev efforts from CPython.
So are there political, personal or business issues?
> can’t everyone refocus the efforts
You have answered your own question.
Seriously, though. PyPy is 2-3 versions behind CPython (3.11 vs 3.14) and it's not even 100% compatible with 3.11. Libraries such as psycopg and lxml are not fully supported. It's a hard sell.
Pypy only has a handful of devs. If it had the PSF's official blessing, it wouldn't lag behind CPython so much.
But this is exactly my point. The resources pypy has are much smaller. And still for years they managed to follow up being just 2-3 versions behind with features and high on performance.
So why not move all the resources from CPython to close the gap with features faster and replace CPython entirely?
Since this is not happening I expect there to be serious reasons, but I fail to see them. This is what I ask for.
> Are there any serious technical reasons not to do it?
Forget technical reasons, how would you ever do it? It feels like the equivalent of cultural reprogramming "You must stop using your preferred interpreter and halt all your efforts contrary to the one true interpreter". Nah, not going to happen in a free and open source language. Who would have the authority and control to make such a directive?
Yes, there may be technical reasons, but the reason it doesn't happen more than any other is that programming languages are languages spoken by people, and therefore they evolve organically at no one's direction. Even in languages like Python with a strong bent for cultural sameness and a BDFL type direction, they still couldn't control it. Often times, dialects happen for technical reasons, but it's hard to get rid of them on technical grounds.
> pypy which is already much faster
It isn't.
For all my applications, going to PyPy was an instant 2x improvement.
Not only that, it is a lot easier to hack on. I might be biased, but the whole implementstion idea of PyPy seems a lot more sane.
I think for pure python performance it is significantly faster at least on all the benchmarks I have seen. That said a lot of what people actually do in python calls into libraries that are written in C++ or C, which I believe has a similar performance (when it works) on pypy.
> when it works
This is the problem!
Yes it is.
The most interesting part for me is that PyPy is faster than free threaded CPython even on multi threaded code.
pypy has frequently struggled with funding. Here's a link if you want to donate this christmas https://opencollective.com/pypy
Do any of these tests measure the new experimental tail call interpreter (https://docs.python.org/3.14/using/configure.html#cmdoption-...)?
I couldn't find any note of it, so I would assume not.
It would be interesting to see how the tail call interpreter compares to the other variants.
The build of Python that I used has tail calls enabled (option --with-tail-call-interp). So that was in place for the results I published. I'm not sure if this optimization applies to recursive tail calls, but if it does, my Fibonacci test should have taken advantage of the optimization.
The tail calls in question are C tail calls inside the inner interpreter loop. They have nothing to do with Python function calls.
That tells you how much I know about the feature. :) But in any case, I'm positive that the flag was enabled, so my results are with tail calls. I suppose part of the difference between 3.13 and 3.14 could be thanks to this.
Good to know! Thanks for confirming. Yes, I would guess that the tail call interpreter explains part of the difference between 3.13 and 3.14. Previously the overall improvement to the interpreter has been measured at 1-5%, or even 10-15% depending on the compiler version you are using: https://blog.nelhage.com/post/cpython-tail-call/
If your benchmark setup is easy to re-run, it would be awesome to see numbers that compare the tail call interpreter to the build where it is disabled, to isolate how much improvement is due to that.
It wouldn’t have, since
isn’t a tail call—there’s work left after the recursive calls, so the tail call interpreter can’t optimize it.For quick and dirty Python benchmark, try https://github.com/DarkStar1982/fast_langton_ant/
Run as "python3 server.py -s 10000000 -n"
It remains solidly among the slowest languages you could choose. Consider your use case and the trade-offs wisely.
What are the reasons why nobody uses pypy?
A lot of Python use cases don't care about CPU performance at all.
In most cases where you do care about CPU performance, you're using numpy or scikit learn or pandas or pytorch or tensorflow or nltk or some other Python library that's more or just a wrapper around fast C, C++ or Fortran code. The performance of the interpreter almost doesn't matter for these use cases.
Also, those native libraries are a hassle to get to work with PyPy in my experience. So if any part of your program uses those libraries, it's way easier to just use CPython.
There are cases where the Python interpreter's bad performance does matter and where PyPy is a practical choice, and PyPy is absolutely excellent in those cases. They just sadly aren't common and convenient enough for PyPy to be that popular. (Though it's still not exactly unpopular.)
It doesn't play nice with a lot of popular Python libraries. In particular, many popular Python libraries (NumPy, Pandas, TensorFlow, etc.) rely on CPython’s C API which can cause issues.
FWIW, PyPy supports NumPy and Pandas since at least v5.9.
That said, of all the reasons stated here, it's why I don't primarily use PyPy (lots of libraries still missing)
But pypy doesn’t necessarily perform as well, and it can’t jit compile the already compiled C code in numpy, so any benefits are often lost.
Speaking only for myself, and in all sincerity: every year, there is some feature of the latest CPython version that makes a bigger difference to my work than faster execution would. This year I am looking forward to template strings, zstd, and deferred evaluation of annotations.
Keep in mind that the two scripts that I used in my benchmark are written in pure Python, without any dependencies. This is the sweet spot for pypy. Once you start including dependencies that have native code their JIT is less efficient. Nevertheless, the performance for pure Python code is out of this world, so I definitely intend to play more with it!
Because in the real world, for code where performance is needed, you run the profiler and either find that the time is spent on I/O, or that the time is spent inside native code.
This might have been your experience, but mine has been very different. In my experience a typical python workload is 50% importing python libraries, 45% slow python wrapper logic and 5% fast native code. I spend a lot of time rewriting the python logic in C++, which makes it 100x faster, so the resulting performance approaches "10% fast native logic, 90% useless python imports".
Imports being slow is annoying, but only matters to short running code.
Many simple scripts at my work that more or less just argparse and fire off an HTTP request spend half a minute importing random stuff because of false deps and uncommon codepaths. For some unit tests it's 45 seconds, substantially longer than the time taken to run the test logic.
In dev cycles most code is short-running.
> Many simple scripts at my work [...] For some unit tests it's 45 seconds
> I spend a lot of time rewriting the python logic in C++, which makes it 100x faster
Nice! Your workplace didn't care to pick a better tool for the job in the past, and it seems to not care what you're doing at present, if you have to spend time rewriting the stuff in C++, instead of picking Nim and calling it a day, in a day.
Have you thought about packing that stuff into an executable or precomputing or preloading it? There's techniques for each of those things that help in some scenarios.
There is more than one PEP related to making imports faster such as PEP 690 or PEP 810. It's definitely a well-known problem. The solution is probably right around the corner.
If imports are slow, you need to not be writing python in the first place, because you are either on limited hardware or you are writing a very performant app.
When it's a drop-in replacement, as in most of my code (and it's dead simple to try if it runs when you use pypy ./main.py), I wouldn't know why you should run the code 5-50% slower for no reason though
IRL you will have CPU-bottlenecked pure Python code too. But it's not enough to take on the unknown risk of switching to a lesser supported interpreter. Worst case you just put in the effort to convert the hot parts to multiprocessing.
I do a bit of performance work and find most often that things are mixed: there’s enough CPU between syscalls that the hardware isn’t being full maximized, but there’s enough I/O the CPUs aren’t pegged either. It is rare that the profiler finds an obvious hotspot that yields an easy win; usually it shows that with heavy refactoring you can make 10% of your load several times faster, and then you’ll need to do the same for the next 10% and so on. That is the more typical real world for me, and in that world Python is really awful when compared to rewrite-it-in-Rust.
This "There are no hot spots, it's just a uniform glowing orange" situation is why Google picked C++ and then later Rust and to some extent why they picked Go too.
Also, that engineer time you would spend optimizing for performance costs more than just throwing more hardware at it.
For cloud jobs that can be true, but for single threaded dev-in-the-loop work you can't just buy a 100x faster processor than the one on their dev machine, and the latency is expensive workflow friction.
That's the thing with single threaded CPU operations, you can't throw more hardware at it
In this situation, "more hardware" would mean throwing a faster CPU at it.
It caps out quickly. If you have a newish Mac, you're already pretty much at the max.
Not if you have certain types of scientific data. You can't rent enough hardware to run the slow code.
I use it where I can, unfortunately those places are usually scripts that don’t benefit from the compiler.
The project is moving into maintenance mode, if some folks want to get python-famous, go support pypy.
We look periodically and pypy is usually unusable for us due to third-party library support. E.g. psycopg2, at least as of a couple years ago. Have not checked in a while.
pypy has a c-extension compatibility layer that allows running psycopg2 (via psycopg2cffi) and similar for numpy etc.
I think generally people who care about performance don't tend to write their code in Python to begin with, so the culture of python is much less performance sensitive than is typical even among other interpreted languages like perl, php, ruby or javascript. The people who do need performance, but are still using python, tend to rely on native libraries doing significant numerical calculations, and many of these libraries are not compatible with PyPy. The escape hatch there is to offload more and more of the computation into the native runtime rather than to optimize the python performance.
Because it hasn't been blessed by the PSF. Plus it's always behind, so if you want to use the newest version of framework x, or package y then you're SOL.
Python libraries used to brag about being pure Python and backwards compatible, but during the push to get everyone on 3.x that went away, and I think it is a shame.
It currently only supports Python 3.11. That is a big reason.
I was happy to see it supports a fairly recent Python3 at all now, like Py3.5 or what is it that ships with most of the expected stuff? Works for me, I'd target something like that for compatibility anyway
I keep wondering the same. It's a significant speed-up in most cases and equally easy to (apt) install
For public projects I default the shebang to use `env python3` but with a comment on the next line that people can use if they have pypy. People seem to rarely have it installed but they always have Python3 (often already shipped with the OS, but otherwise manually installed). I don't get it. Just a popularity / brand awareness thing I guess?
The advantage of core python is that you import stuff and 99.999999% of the time it works.
With PyPy not so much.
It's not easily available in uv. Even if I installed it outside uv, it always seems significantly out of date. I'm running code in spaces where with uv I can control all the installs of Python, so I don't benefit from using an older release for compatibility.
Personally: cpyext always lags changes in the CPython ABI and headers which my code relies on, or I'm relying on internals which cpyext doesn't implement at all
We want the new features more than we want performance!
Also: there are some libraries that just don't work on pypy.
Because all the heavy number-crunching code is already written in C or Rust or as CUDA kernels, so the actual time spent running Python code is miniscule. If it starts to matter, I would probably reach for Cython first. PyPy is an extremely impressive project, but using it adds a lot of complexity to what is usually a glue language. It is a bit like writing a JIT for Bash.
because it turns out that optimizing performance of a programming language designed for use-cases where runtime performance doesn't matter ... doesn't matter
There's currently talk of adding gigawatts of data center capacity to the grid just for use cases where python dominates development. While a lot of that will be compiled into optimized kernels on CPU or GPU, it only takes a little bit of 1000x slower code to add up to a significant chunk of processing time at training or inference time.
What percentage of the CPU cycles are actually spent running Python though? My impression is _very_ low in production LLM workloads. I think significantly less than 1%. There are almost certainly better places to spend the effort, and if it did matter, I think they would replace Python with something like C++ or Rust.
Might as well take the work that's already done though? I can't think of a logical reason why you'd want to run it at potentially half the speed (depending on the hot code specifics how much, if any, speedup you get of course)
Can't run PyTorch on PyPy.
I've never experienced any problems that could be attributed to the speed of my Python runtime. I use Python a lot for internal scripting and devops work, but never in a production environment that scaled beyond a few hundred users. I suspect most Python usecases are like that, and CPython is just the safest option.
Yeah I'm curious about this myself. Seems to utterly destroy CPython in every one of those benchmarks.
3.1415.. Pithon??
called it https://bsky.app/profile/ssg.dev/post/3lwyoye7suk26
My first thought as well lol
Pithon, haha
This version runs circles around other languages. Well ... half a circle, anyway.
First there was PyPI and pypy, now there is PiPy
Hopefully Pipi (German for pee) won't come anytime soon. But enough bad jokes for today.
PyPi, right?
Can't wait for PyPyPi.
πthon
Or Pijthon in Dutch.
Hej! Nijce!
Not Pijthon?
I feel like I’m having a stroke.
You should hear the Dutch say "yah-vah-shchkript" with a throat clear and spit take.
The Dutch pronunciation of javascript differs from the English one only in the first syllable. Roughly zero dutchies would insert the Dutch schr- sound in a loanword, and even fewer would do that while leaving the foreign -ipt suffix intact.
Maybe they're just taking advantage of the opportunity to expectorate then.
'3.14159265359...' - there is a lot of room to grow - keep it at pi
Missed opportunity for "Pi thon 3.14 is here. How fast is it?"
Is fold comment a option based on karma or something? I loved the most voted post here on how Miguel helped the guy but, it is unrelated and for the first time I guess I realized there is no fold so I can go to people actually talking about the article...
You got more karma than me, so you're probably just looking past it. It's the [-] button on the right end of the comment header, just to the right of the "next" button.
For all those making πthon jokes: https://github.com/python/cpython/pull/125035
seems loved languages such as python & ruby (ZJIT | TruffuleRuby) have been getting a lot performance improvements lately. of course JS with v8 kickstarted this - followed by PHP.
so for majority of us folks use what you love - the performance will come.
As someone who was a hardcore python fanboy for a long time, no, no it won't. There are classes of things that you can only reasonably do in a language like rust, or where go/kotlin will save you a crazy amount of pain. Python is fine for orchestration and prototyping, but if it's the only arrow you have in your quiver you're in trouble.
Completely agree, Python is great for its simple syntax, C-interop and great library ecosystem, but it is a pain to debug, deploy, and maintain in more complex use cases, and doesn't play as nicely as other languages with modern stacks (eg. k8s). What is pleasure for the developer (no explicit typing, wild i/o-as-you-go, a library for everything) is pain for the maintainer (useless error messages, sudden exceptions of lacking UAC, dependency hell).
Go, Kotlin and Rust are just significantly more modern and better designed, incorporating the lessons from 90s languages like Python, Ruby and Java.
I know sometimes performance doesn’t matter, and python is certainly useful, but it’s not fast. It can be fast enough and they’ve put a lot of effort into making fast libraries (called in c).
When doing bioinformatics we had someone update/rewrite a tool in java and it was so much faster. Went from a couple days to some like 4 hours of runtime.
Python certainly can be used in production (my experience maintaining some web applications in Java would make me reach for python/php/ruby to create a web backend speed be dammed). Python has some great libraries.
I even changed to JS as my fave for backends. Still using Py for other stuff ofc, but I'm constantly missing some of the JS niceties.
At least Python doesn't have an extremist "100% Pure" ideology like Java, and instead (like TCL and Lua) it's been designed from the ground up for easily integrating with other languages and libraries, embedding, and extending, instead of Java's intolerantly weaponized purity and linguistic supremacy.
Reasons why Sun and Java failed:
Strategy over product. McNealy cast Java as a weapon of mass destruction to fight Microsoft, urging developers to "evangelize Java to fight Microsoft." That fight-first framing made anti-Microsoft positioning the goal line, not developer throughput.
Purity over pragmatism. Sun’s "100% Pure Java" program explicitly banned native methods and dependencies outside the core APIs. In practice, that discouraged bridges to real-world stacks and punished teams that needed COM/OS integration to ship. (Rule 1: "Use no native methods.")
"100% Pure Java" has got to be one of the worst marketing slogans in the history of programming languages, signaling absolutism, exclusion, and gatekeeping. And it was technically just as terrible and destructive an idea that held Java back from its potential as an inclusive integration, extension, and scripting language (especially in the web browser context, since it was so difficult to integrate, that JavaScript happened instead and in spite of Java).
Lua, Python, and even TCL were so much better and successful at embedding and extending applications than Java ever was (or still is), largely because they EMBRACED integration and REJECTED "purity".
Java's extremist ideological quest for 100% purity made it less inclusive and resilient than "mongrel" languages and frameworks like Lua, Python, TCL, SWIG, and Microsoft COM (which Mozilla even cloned as "XP/COM"), that all purposefully enabled easy miscegenation with existing platforms and libraries and APIs instead of insanely insisting everyone in the world rewrite all their code in "100% Pure Java".
That horrible historically troubling slogan was not just a terrible idea technically and pragmatically, but it it also evoked U.S. nativist/KKK's "100% Americanism", Nazi's "rassische Reinheit", "Reinhaltung des Blutes", and "Rassenhygiene", Fascist Italy's "La Difesa della Razza", and white supremacist's "white purity". It's no wonder Scott McNealy is such a huge Trump supporter!
While Microsoft courted integrators. Redmond pushed J/Direct / Java-COM paths, signaling "use Windows features from Java if that helps you deliver." That practicality siphoned off devs who valued getting stuff done over ideological portability.
Community as militia. The rhetoric ("fight," "evangelize") enlisted developers as a political army to defend portability, instead of equipping them with first-rate tooling and sanctioned interop. The result: cultural gatekeeping around "purity" rather than unblocking use cases.
Ecosystem costs. Tooling leadership slid to IBM’s aptly named Eclipse (a ~$40M code drop that became the default IDE), while Sun’s own tools never matched Eclipse’s pull: classic opportunity cost of campaigning instead of productizing.
IBM's Eclipse cast a dark shadow over Sun's "shining" IDE efforts, which could not even hold a candle to Microsoft's Visual Studio IDE that Sun reflexively criticized so much without actually bothering to use and understand the enemy.
At least Microsoft and IBM had the humility to use and learn from their competitor's tools, in the pursuit of improving their own. Sun just proudly banned them from the building, cock-sure there was nothing to learn from them. And now we are all using polyglot VSCode and Cursor, thanks to Microsoft, instead of anything "100% Pure" from Sun!
Litigation drain. Years of legal trench warfare (1997 suit and 2001 settlement; then the 2004 $1.6B peace deal) defended "100% Pure Java" but soaked time, money, and mindshare that could have gone to developer-facing capabilities.
Optics that aged poorly. The very language of "purity" in "100% Pure Java" read as ideological and exclusionary to many -- whatever Sun's presumed intent -- especially when it meant "rewrite in Java, don’t integrate." The cookbook literally codified "no native methods," "no external libraries," and even flagged Runtime.exec as generally impure.
McNealy’s self-aggrandizing war posture did promote Java’s cross-platform ideal, but it de-prioritized developer pragmatism -- stigmatizing interop, slow-rolling mixed-language workflows, and ceding tools leadership -- while burning years on lawsuits. If your priority was "ship value fast," Sun’s purity line often put you on the wrong side of the border wall.
And now finally, all of Java's remaining technical, ideological, and entrenched legacy enterprise advantages don't matter any more, alas, because they are all overshadowed by the unanthropomorphizable lawnmower that now owns it and drives it towards the singular goal of extracting as much profit from it as possible.
How did they not take the opportunity with this version to rename it pi-thon?
Because they knew you would…
No comparison to Python 2.7.18.
So finally we can call it π-thon?
Very nice post - it's good to see benchmarks done for humans.
For fun, I tried this in Raku:
lolSeriously, Python is doing great stuff to squeeze out performance from a scripting language. Realistically, Raku has fewer native libraries (although there is Inline::Python) and the compiler still has a lot of work to get the same degree of optimisation (although one day it could compare).
EDIT: for those who have commented, yes you are correct … this is a “cheat” and does not seek to state that Raku is faster than Python - as I said Raku still has a lot of work to do to catch up.
I take it this is supposed to be the equivalent of fib(40), which ran on the author's system in Pyπ in 6.59 seconds and apparently on yours, with Raku, in 0.21?
Do you have the same hardware as the author or should one of you run the other's variant to make this directly comparable?
No, this is very much not the same. The Raku version is like writing this in Python:
And taking the 40th element. It's not comparable at all to the benchmark, that's deliberately an extremely slow method of calculating fibonacci numbers for the purpose of the benchmark. For this version, it's so fast that the time is dominated by the time needed to start up and tear down the interpreter.Well, sure; you're using dynamic programming, while the stress test Python Fibonacci code is deliberately using recursion without memoization — it makes function calls proportionate to the number computed. Most of the time you're seeing in the Raku code is the interpreter startup. Python doesn't have syntax strongly oriented towards that sort of trick (it's not as strong of a second-best APL as it is a second-best Lisp or Haskell), but:
(Or a "lazy iterator" approach:)That >2x performance increase over 3.9 in the first test is pretty impressive. A narrow use case for sure, but assuming you can leave your code completely alone and just have it run on a different interpreter via a few CLI commands, that's a nice bump.
Very interesting post, thanks for putting it together.
Rust is indeed quite fast, I thought NodeJS was much better tbh., although it's not bad. I'd be interested to learn what's holding it back because I've seen many implementations where V8 can get C++-like performance (I mean it's C++ after all). Perhaps there's a lot of overhead in creating/destroying temporary objects.
> V8 can get C++-like performance (I mean it's C++ after all)
I don’t think that follows. Python is written in C, but that doesn’t mean it can get C-like performance. The sticking point is in how much work the runtime has to do for each chunk of code it has to execute.
(Edit: sorry, that’s in reply to another child content. I’m on my phone in a commute and tapped the wrong reply button.)
One reason is that I did not spend much time optimizing the Node and Rust versions, I just translated the Python logic as directly and quickly as I could. At least I did not ask an LLM to do it for me, which I hope counts. ;-)
Edit: fixed a couple of typos.
V8 gets C++-like performance when it is getting code that JITs very well. This is typically highly-numeric code, even sometimes tuned specifically for the JIT. This tends to cause a great deal of confusion when people see the benchmarks for that highly numeric code and then don't understand why their more conventional code doesn't get those speeds. It's because those speeds only apply to code you're probably not writing.
If you are writing that sort of code, then it does apply; the speed for that code is real. It's just that the performance is much more specific than people think it is. In general V8 tends to come in around the 10x-slower-than-C for general code, which means that in general it's a very fast scripting language, but in the landscape of programming languages as a whole that's middling single-thread performance and a generally bad multiprocessing story.
For the bubble sort implementation, it's due to the use of the destructuring assignment in the benchmark code. When swapping to a regular swap using a temporary variable, the benchmark runs more than 4 times faster on my machine. Still not at Rust level of performance, but a bit closer to it.
Only tested against NodeJS and Rust
What about Lua and LuaJIT
If faster language interpreters were included in the tests, the title could be "Python 3.14 is here. How slow is it?"
It would be interesting to test intepreter startup time across various intepreter including Python
I did some recent testing that showed both Lua and LuaJIT-joff (its interpreter-only mode) to be about 2x faster than Python. Both PyPy and full-on LuaJIT were about 10x faster.
Years ago, I even found Ruby to be faster than Python. This was back in the Ruby 2.0 / Python 3.5 days - I'd be interested to know if it's still the case.
In my experience LuaJIT is extremely fast in comparison to Python. Perl is faster, too.
Kinda curious. Have you figured out why the code runs faster on a Mac?
It's two different computers with different CPUs, so different runtimes are expected and has nothing to do with the OS.
> Framework laptop running Ubuntu Linux 24.04 (Intel Core i5 CPU)
> Mac laptop running macOS Sequoia (M2 CPU)
Yes, and why? way to not address the question at all.
Are you asking why the M2 is faster than the i5?
Well I was asking whether there is something in the Mac Kernel which makes it faster or is it just the different CPUs/Memory that account for this?
According to general benchmarks Apple Silicon is the highest performing CPU for single-threaded work. It'll be hard to confirm how much of a difference the OS factors in but the hardware difference is most likely why.
Gees, Rust is fast!
I feel like Python should be much faster already. With all the big companies using Python and it's huge popularity I would have expected that a lot of money, work and research would be put into making Python faster and better.
The Faster CPython project was from one of "the big companies" and did make significant progress with each version of Python, even if some of its more ambitious goals weren't met. The results of which you're seeing in the benchmarks in this blog post.
Why?
There are other languages you can use to make stuff go fast. Python isn't for making stuff go fast. Its for rapid dev, and that advantage matters way more when you already are going to be slow due to waiting for network response
This has always confused me... is Python really that much better at rapid dev? I work on a Python project and every day I wish the people that started the project had chosen a different language that actually scaled well with the problem rather than Python, which they likely chose because it was for "rapid dev".
You can run Python processes in parallel for "scaling". Youtube and Uber run python backends. This is cheaper than developer time per hour.
Here's hoping they make 16 patch versions
I hope they speedrun to Python 6.28 because tau > pi
(mini unrelated rant. I think pi should equal 6.28 and tau should equal 3.14, because pi looks like two taus)
> I think pi should equal 6.28 and tau should equal 3.14, because pi looks like two taus
Ha. Undeniable proof that we had them backwards all along!
Does 3.14.0 count as one of those 16? I’m more interested in the 3.14.15 than the correctly rounded up 3.14.16.
Yes hah.
> I’m more interested in the 3.14.15
That was indeed the joke
object oriented developer language, whereas the API is the mass-production of backend apps
Pi-thon
For a while the language will be named PIthon
https://archive.ph/W0IL2
πthon
I started using Python again recently after a 15 year break. The reason was I started working with LangChain, specifically LangGraph agents. The JavaScript/TypeScript versions are months behind. In the AI world with the progress thats been made recently, months might as well be years.
python pi!
I’m very glad python is getting faster. But the correct answer to “Is Python Really That Slow?” is unambiguously YES. Unless you’re using some ML library like torch or numpy which spends all its time in optimized C code, python is still EXTREMELY slow. We are going to need a lot of these 10% improvements for python to be comparable to Go, Java, or Node, each of which are about 30x faster on typical computer tasks.
Pi-thon?
I know this is not a highquality comment, but this must be the ideal language to run on a raspberry Pi. I'll see myself out; I also do Bar Mitzwahs.
Aha, the perfect time for Python to adopt the TeX version numbering system.
Yeah honestly I don't really care about these benchmarks. Python isn't built for raw performance and that's totally fine! It's the number one choice for prototyping and can do so much, that's what actually matters. I think it's cool they're working on speed improvements though, means my prototype-to-production cycle gets a bit smoother lol.
So, Π-thon?
I'm thankful they included a compiled language for comparison, because most of the time when I see Python benchmarks, they measure against other versions of Python. But "fast python" is an oxymoron and 3.14 doesn't seem to really change that, which I feel most people expected given the language hasn't fundamentally changed.
This isn't a bad thing; I don't think Python has to be or should be the fastest language in the world. But it's interesting to me seeing Python getting adopted for a purpose it wasn't suited for (high performance AI computing). Given how slow it is, people seem to think there's a lot of room for performance improvements. Take this line for instance:
> The free-threading interpreter disables the global interpreter lock (GIL), a change that promises to unlock great speed gains in multi-threaded applications.
No, not really. I mean, yeah you might get some speed gains, but the chart shows us if you want "great" speed gains you have two options: 1) JIT compile which gets you an order of magnitude faster or 2) switch to a static compiled language which gets you two orders of magnitude faster.
But there doesn't seem to be a world where they can tinker with the GIL or optimize python such that you'll approach JIT or compiled perf. If perf is a top priority, Python is not the language for you. And this is important because if they change Python to be a language that's faster to execute, they'll probably have to shift it away from what people like about it -- that it's a dynamic, interpreted language good for prototyping and gluing systems together.
I've been writing Python professionally for a couple of decades, and there've only been 2-3 times where its performance actually mattered. When writing a Flask API, the timing usually looks like: process the request for .1ms, make a DB call for 300ms, generate a response for .1ms. Or writing some data science stuff, it might be like: load data from disk or network for 6 seconds, run Numpy on it for 3 hours, write it back out for 3 seconds.
You could rewrite that in Rust and it wouldn't be any faster. In fact, a huge chunk of the common CPU-expensive stuff is already a thin wrapper around C or Rust, etc. Yeah, it'd be really cool if Python itself were faster. I'd enjoy that! It'd be nice to unlock even more things that were practical to run directly in Python code instead of swapping in a native code backend to do the heavy lifting! And yet, in practice, its speed has almost never been an issue for me or my employers.
BTW, I usually do the Advent of Code in Python. Sometimes I've rewritten my solution in Rust or whatever just for comparison's sake. In almost all cases, choice of algorithm is vastly more important than choice of language, where you might have:
* Naive Python algorithm: 43 quadrillion years
* Optimal Python algorithm: 8 seconds
* Rust equivalent: 2 seconds
Faster's better, but the code pattern is a lot more important than the specific implementation.
> Or writing some data science stuff, it might be like: load data from disk or network for 6 seconds, run Numpy on it for 3 hours, write it back out for 3 seconds.
> You could rewrite that in Rust and it wouldn't be any faster.
I was asked to rewrite some NumPy image processing in C++, because NumPy worked fine for 1024px test images but balked when given 40 Mpx photos.
I cut the runtime by an order of magnitude for those large images, even before I added a bit of SIMD (just to handle one RGBX-float pixel at a time, nothing even remotely fancy).
The “NumPy has uber fast kernels that you can't beat” mentality leads people to use algorithms that do N passes over N intermediate buffers, that can all easily be replaced by a single C/C++/Rust (even Go!) loop over pixels.
Also reinforced by “you can never loop over pixels in Python - that's horribly slow!”
Fused expressions are possible using other libraries (numexpr is pretty good), but I agree that there's a reluctance to use things outside of NumPy.
Personally though I find it easier to just drop into C extensions at the point that NumPy becomes a limiting factor. They're so easy to do and it lets me keep the Python usability.
Same with opencv and even sometimes optimized matrix libraries in pure C++. These are all highly optimized. But often when you want to achieve something you have to chain stuff which quickly eats up a lot of cycles, just by copying stuff around and having multiple passes that the compiler is unable to fuse. You can often pretty easily beat that even if you are not an optimization god by manual loop fusion.
That's because you're doing web stuff. (I/O limited). So much of our computing experience has been degraded due to this mindset applied more broadly. Despite a steady improvement in hardware, my computing experiences have been stagnating and degraded in terms of latency, responsiveness etc.
I'm not going to even go into the comp chem simulations I've been running, or that about 1/3 the stuff I do is embedded.
I do still use python for web dev, partly because as you say, it's not CPU-bound, and partly because Python's Django framework is amazing. But I have switched to rust for everything else.
As a java backend dev mainly working on web services, I wanted to like python, but I have found it really hard to work on a large python project because the auto complete just does not work as well as something like java.
Maybe it is just due to not being as familiar with how to properly setup a python project, but every time I have had to do something in a django or fast api project it is a mess of missing types.
How do you handle that with modern python? Or is it just a limitation of the language itself?
Pycharm has been fine. Just disable the AI stuff and you get accurate completion. It even has completion for Django ORM stuff, which is heavily dynamic.
That's 100% an IDE thing. I use Zed (or Emacs or anything else supporting an LSP) and autocomplete is fast and accurate.
I won’t completely argue against that, and I’ve also adopted Rust for smaller or faster work. Still, I contend that a freaking enormous portion of computing workloads are IO bound to the point that even Python’s speed is Good Enough in an Amdahl’s Law kind of way.
I hear this a lot, but can you really say that you're consistently saturating a 1Gbps line for netcode or 6+ Gbps nvme for disk data? In my experience this doesn't really happen with code that isn't intentionally designed to minimize unnecessary work.
A lot of slow parsing tends to get grouped in with io, and this is where python can be most limiting.
I don't personally use Python directly for super IO intensive work. In my common use cases, that's nearly always waiting for a database to return or for a remote network API to respond. In my own work, I'm saturating neither disk nor network. My code often finds itself waiting for some other process to do that stuff on its behalf.
It's been said that Python's greatest superpower is that it's the second-best language at the most stuff.
No one's really developed an ecosystem for a language that's more performant that can match it, and that's all it needs to assert dominance.
I've never understood this. Python cannot be optimized like C, C++ or Rust. It cannot do advanced functional things like OCaml, Haskell or Scala. It cannot run in browsers like TypeScript. It cannot do games programming like C# and it can't do crazy macro stuff like Clojure. I don't think it's even second best at those things.
I'm reading this as, "It cannot do things the best", and that's correct. It can't.
But it can do them well enough, and enough people know it that they can drag a solution across the line in most domains.
> That's because you're doing web stuff.
I guess you didn't notice where he talked about running numpy?
And 300ms for a DB call is slow, in any case. We really shouldn't accept that as normal cost of doing business. 300ms is only acceptable if we are doing scrypt type of things.
> in any case.
In some cases. Are looking up a single indexed row in a small K-V table? Yep, slow. Are you generating reports on the last 6 years of sales, grouped by division within larger companies? That might be pretty fast.
I'm not sure why you'd even generalize that so overly broadly.
To put in perspective, 300ms is about looping over 30GiB data from RAM, loading 800MiB data from SSD, or doing 1TFLOPS on a single core computer.
300ms to generate a report would be able to go through ~100M rows at least (on a single core).
And the implicit assumption that comment I made earlier, of course is not about the 100M rows scan. If there is a confusion, I am sorry.
That's all true, so long as you completely ignore doing any processing on the data, like evaluating the rows and selectively appending some of them into a data structure, then sorting and serializing the results, let alone optimizing the query plan for the state of the system at that moment and deciding whether it makes more sense to hit the indexes or just slurp in the whole table given that N other queries are also executing right now, or mapping a series of IO queries to their exact address in the underlying disks, and performing the parity checks as you read the data off the RAID and combine it into a single, coherent stream of not-block-aligned tuples.
There's a metric boatload of abstractions between sending a UTF-8 query string over the packet-switched network and receiving back a list of results. 300ms suddenly starts looking like a smaller window than it originally appears.
There is nothing for us to take away in this discussion. So let me be the first to tune down: all I want to say is: don't take that 300ms as given, it sits in this uncomfortable region too short to be an async op and too long to be noticeable (anything between 50ms and 2s fits this bill). Most likely the query is doing something suspicious and would benefit the most to take a closer look at.
I was totally with you until that last sentence, then you lost me again.
Saying a DB query is too long by giving an arbitrary number is like saying a rope is too long. That’s solely dependent on what you’re doing with it. It’s literally impossible to say that X is too long unless you know what it’s used for.
Sure then you get a developer who decides to go with Flask for an embedded product and it's an eye watering slog.
People will always make bad decisions. For example, I'd also squint at a developer who wanted to write a new non-performance-critical network service in C. Or a performance-critical one, for that matter, unless there was some overwhelming reason they couldn't use Rust or even C++.
Advent of code is deliberately set up to be doable in Python. You can also imagine a useful problem which Rust takes 2 weeks to do, how long would it take in Python?
And my experience is this: you start using ORMs, and maybe you need to format a large table once in a while. Then your Python just dies. Bonus points if you're using async to service multiple clients with the same interpreter.
And you're now forced to spend time hunting down places for micro-optimizations. Or worse, you end up with a weird mix of Cython and Python that can only be compiled on the developer's machine.
Exactly, most Python devs neither need nor care about perf. Most applications don't even need perf, because whether it's .1 second or .001 seconds, the user is not going to notice.
But this current quest to make Python faster is precisely because the sluggishness is noticeable for the task it's being used for most at the moment. That 6 second difference you note between the Optimal Python and the optimal Rust is money on the table if it translates to higher hardware requirements or more server time. When everything is optimal and you could still be 4x faster, that's a tough pill to swallow if it means spending more $$$.
> most Python devs neither need nor care about perf.
You do understand that's a different but equivalent way of saying, "If you care about performance, then Python is not the language for you.", don't you?
"Logically equivalent" is a very limited subset of "equivalent (in meaning)". Language is funny like that.
Yes, I'm consistent in that. What I don't get is if that's the case, why is there such a focus on improving Python perf? At best they're getting marginal improvements on something that most Python devs claim they don't care about, and which they say is not important for Python as a language due to JIT, C interop, and so on.
I think perhaps their hope is that eventually Python can get to Go-level if not Rust-level performance if they keep up the optimizations. I do personally believe this to be possible. The motivating example is Julia, which is a high level language with low-level language's performance. After arriving there, developers will care.
I agree, I think that's probably the hope. It's interesting you bring up Julia here because I was just reading the post about the 1.12 release and this comment struck me:
https://news.ycombinator.com/item?id=45524485
Particularly this part is relevent to the Python discussion:
So that's the question I have right now: what is Python supposed to be? Is it supposed to be the glue language that is easy to use and bind together a system made from other languages? Or is it trying to be what Julia is, a solution to the two language problem. Because it's not clear Julia itself has actually solved that.The reason I bring this up is because there's a lot of "cake having/eating" floating around these types of conversations -- that's it's possible to be all the things, without a healthy discussion of what the tradeoffs are in going that direction, and what that would me mean for the people who are happy with the way things are. These little % gains are all Python is going to achieve without actually asking the developer to sacrifice their development process in some way.
I think Julia has largely not solved it because it is clunky to use for purposes other than scientific computing. Python can't be argued to be that, it's very nice for web development as well as scientific computing, the issue is just that for non-scientific computing use cases the perf. isn't great.
If you think Python is nice for scientific computing, you must have never tried Matlab. Python is pretty clunky in comparison in its syntax for scientific computing.
I used MATLAB for about 5 years, and then Mathematica, before switching to Python. I even had a job offer to work at MathWorks in Cambridge in about 2014!
And you still think Python has superior matrix manipulation syntax? Because that's at the core of scientific computing.
LOL, python is plenty fast if you make sure it calls C or Rust behind the scenes. Typical of 'professional' python people. Something too slow? just drop into C. It surely sounds weird to everyone who complains about Python being slow and the response is on these lines.
But that’s the whole point of it. You have the option to get that speed when it really matters, but can use the easier dynamic features for the very, very many use cases where that’s appropriate.
This is an eternal conversation. Years ago, it was assembler programmers laughing at inefficient C code, and C programmers replying that sometimes they don’t need that level of speed and control.
You are correct. However it took about only about 10 years for C compilers to beat hand assembly (for the average programmer), thus proving the naysayers wrong.
Meanwhile Python is just as slow today as it was 30 years ago (on the same machine).
People really misconstrue the relationship between Python and C/C++ in these discussions.
Those libraries didn't spring out of thin air, nor were they ever existing.
People wanted to write and interface in python badly, that's why you have all these libraries with substantial code in another language yet research and development didn't just shift to that language.
TensorFlow is a C++ library with a python wrapping. Pytorch has supported C++ interface for some time now, yet virtually nobody actually uses tensorflow or pytorch in C++ for ML R&D.
If python was fast enough, most would be fine, probably even happy to ditch the C++ backends and have everything in python, but the reverse isn't true. The C++ interface exists, and no-one is using it. C++ is the replaceable part of this equation. Nobody would really care if Rust was used instead.
Even as a Fortran programmer, the majority of my flops come from BLAS, LAPACK, and those sort of libraries… putting me in the exact same boat as the Python programmers, really. The “professional” programmers in general don’t worry too much about tying their identities to language choices, I think.
This is a very common pattern in high level languages and has been a thing ever since Perl had first come onto the scene. The whole point was that you use more ergonomic, easier to iterate languages like Perl or Python for most of your logic and you drop down into C, C++, Zig, or Rust to write the performance sensitive portions of your code.
When compiled languages became popular again in the 2010s there was a renewed effort into ergonomic compiled languages to buck this trend (Scala, Kotlin, Go, Rust, and Zig all gained their popularity in this timeframe) but there's still a lot of code written with the two language pattern.
This assumes the boundary between Python and the native code is clean and rarely crossed.
And then someone needs to cross FFI border multiple times and gained perf is hurting again.
It's pretty simple. Nobody wants to do ML R&D in C++.
Tensorflow is a C++ library with python bindings. Pytorch has supported a C++ interface for some time now, yet virtually nobody uses C++ for ML R&D.
The relationship between Python and C/C++ is the inverse of the usual backend/wrapper cases. C++ is the replaceable part of the equation. It's a means to an end. It's just there because python isn't fast enough. Nobody would really care if some other high perf language took its place.
Speed is important, but C++ is even less suited for ML R&D.
I think readability is what made python a winner. I can quickly type down my idea like a pseudo code, I can easily skim through other people’s algos. In C++ even a simple algo with a 100 lines of pseudo code will balloon to thousands of lines in c++
[dead]
I agree. Unless they make it like 10x faster it doesn't really change anything. It's still a language you only use if you absolutely don't care whatsoever about performance and can guarantee that you never will.
The counterargument used to be, the heavy lifting will be offloaded to python modules written in C, like numpy.
Which was true, but maybe not the strongest argument. Why not use a faster language in the first place?
But it's different now. There's huge classes of problems where pytorch, jax &co. are the only options that don't suck.
Good luck competing with python code that uses them on performance.
> Why not use a faster language in the first place?
Well for the obvious reason that there isn't really anything like a Jupyter notebook for C. I can interactively manipulate and display huge datasets in Python, and without having to buy a Matlab license. That's why Python took off in this area, really
I believe I heard that argument since before jupyter became popular.
Usually it was accompanied by saying that the time needed to write code is often more important than the time it takes to run, which is also often true.
All that said, jupyter is probably part of python's success, although I'm not the only one who actively avoids it and views it as a bit of a code smell.
I love Jupyter! What I don’t love is people writing large projects in a workbook, then asking how to run it as-is in production so they can continue to iterate on it in that form.
It’s not impossible, but neither is it the sort of thing you want to encourage.
I agree - Jupyter notebook is really the key feature Python has that makes it attractive for research/scientific computing. I would say the REPL too but until very recently it was extremely shoddy so I doubt many people did any serious work in it.
> I would say the REPL too but until very recently it was extremely shoddy
Can you elaborate? I've been using the Python REPL for more than two decades now, and I've never found it to be "shoddy". Indeed, in pretty much every Python project I work on, one of the first features I add for development is a standard way to load a REPL with all of the objects that the code works with set up properly, so I can inspect them.
Very obvious example - you can't paste code containing blank lines.
Another example: navigating this history is done line by line instead of using whole inputs.
It's just bare minimum effort - probably gnu readline piped directly into the interpreter or something.
I think they did improve it a lot very recently by importing the REPL from some other Python interpreter but I haven't upgraded to use that version yet so I don't know how good it is now.
> probably gnu readline piped directly into the interpreter or something
That is more or less how the REPL originally was implemented. I think there's more under the hood there now.
I still don't think what you describe qualifies as "shoddy". There are certainly limitations to the REPL, but "shoddy" to me implies that it's not really usable. I definitely would not agree with that.
The predecessors were really popular before it too - MATLAB in engineering in particular, Mathematica also popular in Physics and Maths departments particularly where the symbolic functionality was more useful. I used both in academia and IPython (later renamed Jupyter) was clearly a natural extension of those but open source, and without the baggage of MATLAB (only one function definition per file, etc.)
>>> you absolutely don't care whatsoever about performance and can guarantee that you never will.
Those are actually pretty good bets, better than most other technological and business assumptions made during projects. After all, a high percentage of projects, perhaps 95%, are either short term or fail outright.
And in my own case, anything I write that is in the 5% is certain to be rewritten from scratch by the coding team, in their preferred language.
Sure but you're still screwing yourself over on that 5% and for no real reason - there are plenty of languages that are just as good as Python (or better!) but aren't as hilariously slow.
And in my experience rewrites are astonishingly rare. That's why Dropbox uses Python and Facebook uses PHP.
Obtuse statement. There are many ways of speeding up a python project if requirements change.
A painful rewrite in another language is usually the only option in my experience.
If you're really lucky you have a small hot part of the code and can move just that to another language (a la Pandas, Pytorch, etc.). But that's usually only the case for numerical computing. Most Python code has its slowness distributed over the entire codebase.
It’s not painful, that’s the point. You have a working prototype now ready to port. (If the destination language is painful perhaps, but don’t do that.)
I recently ported a Python program to Rust and it took me much less time the second time, even though I write Rust more slowly per-line. Because I knew definitively what the program needed.
And if even that is too much optimizing the Python or adding Cython to a few hot loops is less difficult.
I have also ported a Python program to Rust (got a ~50x speedup) but this was a smallish program, under 10k lines of code.
Porting larger programs is rarely tractable. You can tell that because several large companies have decided that writing their own Python runtimes that are faster is less effort (although they all eventually gave up on that as far as I know).
Well, that's not true at all. Scientists care about performance, but it turns out that Python is really good for number crunching since it is really good for using very fast C libraries. I know people who use pandas to manipulate huge datasets from radar astronomy. Also, of course, it's used in machine learning. If Python was "only" used in situations where you don't care about performance, it would not be used in so many scenarios that definitely need high performance. Sure, it is not pure Python, but it's still Python being used, just used to orchestrate C libraries
If you’re actually building and shipping software as a business Python is great. The advantages of Python for a startup are many. Large pool of talent that can pickup the codebase on essentially day 1. Fairly easy to reason about, mature, code velocity, typically one and only one way to do things as opposed to JavaScript. There is way more to the story than raw performance.
It's not that great when you see that the majority of the Python code in businesses is a totally unmaintainable mess because it has incorrect, partial, or no type annotations, and is littered with serious errors that a most basic type checker would flag.
> The advantages of Python for a startup are many. Large pool of talent that can pickup the codebase on essentially day 1.
Large pool of mediocre Python developers that can barely string a function together in my experience.
People use Python for things where performance matters, and it's fine
Probably people at some point were making same arguments about ASM and C. How many people though do ASM these days? Not arguing that for now it is relevant point, obviously Rust / C are way faster.
I doubt it. C is well within 2x of what you can achieve with hand written assembly in almost every case.
Furthermore writing large programs in pure assembly is not really feasible, but writing large programs in C++, Go, Rust, Java, C#, Typescript, etc. is totally feasible.
1980's and 1990's game development says hi.
C compilers weren't up to stuff, that is why books like those from Michael Abrash do exist.
Yep, exactly, It takes time to close the gap so that more and more teams taking that tradeoff
> I doubt it. C is well within 2x of what you can achieve with hand written assembly in almost every case.
Depends what you mean, if you preclude using targeted ASM in your C I think some hot loops can be much slower than 2x.
Of course programs globally written in assembly largely don't make sense.
Let this version be known as PiPy!
pi-thon
Can we call it Py Pi ?
Pi-thon?
more like "pi"thon
honestly if the performance of the python interpreter has a big impact on your application's performance and that's something you care about - you're already doing things very wrong
> And this is a bit disappointing. At least for this test, the JIT interpreter did not produce any significant performance gains, so much that I had to double and triple check that I used a correctly built interpreter with this feature enabled. I do not know much about the internals of the new JIT compiler, but I'm wondering if it cannot deal with this heavily recursive function. FWIW one thing that is worth calling out here is that the initial goal for JIT right now in Python is getting it relatively stable, functional, and more or less getting the initial implementation out there. It's not surprising at all that it's not faster.
I say this because I think the teams working on free-threaded and JIT python maybe could have done a better job publicly setting expectations.
I mean, Guido had a 2021 Faster CPython presentation where they claimed "5x in 4 years (1.5x per year)"[0]. Developers have significantly walked back those expectations since then.
[0] Github slide deck https://github.com/faster-cpython/ideas/blob/main/FasterCPyt...
One important caveat to remember is that this is before a lot of the work on free-threaded python started in full force. A lot of cutting edge work had to be done to support this in the GC but this came with performance penalties. As a result, the trajectory of the Faster CPython effort changed quite a bit.
Didn't help Microsoft axed several folks on that team too...
> Didn't help Microsoft axed several folks on that team too...
Only after the four-year period was over, during which they only delivered a 1.5x - 2x speedup instead of the projected 5x.
Sure, reality is a harsh mistress, but those were really optimistic targets which were used to frame a lot of the development efforts.
[dead]
tl;dr... It's still not fast
tl;dr: Two orders of magnitude slower than Rust, so 2-3 orders slower than native. Python on a 2 GHz processor runs as fast as C on a 2-20 MHz processor.
*for very specific benchmarks, not "on average"
For compute-heavy code "100x slower than C++" is a good rule of thumb in my experience in python 3.10.
True, Python could be better or worse than two orders of magnitude slower for your particular use case, but it's 70x slower for recursion and addition that it clearly hasn't special-cased. That's good to know.
quick n dirty Python code will run faster than quick n dirty C++ code
Pi-thon
Py = 3.14 :')
It's slow. Get back to work.
Get back to writing in other languages when speed matters.
I would tell you a joke about python but it would take you a long time to get it.
You can tell me a joke about Python, but I'll need someone to interpret it.
At least you eventually get it. I regularly don't get UDP jokes.
At least you can come up with a joke quickly with Python
Yeah, but it requires a script!