I wrote a program in Python to read some huge Json files. It took forever to finish. Turned out I could optimize it with some simple changes, which reduced 10 minutes to 10 seconds (not literally, just figurative) and made a difference in huge files only. Later I rewrote the program in Rust. And you know what happened? It was slower than the Python version. Only after understanding what I was doing and making right changes made the Rust version faster.
Most of the time its the design of the code or libraries that slows down. The language might play a huge role in performance, but it depends on what type of code and application it is.
I actually wanted write a blog post about this… if I still have the project data I might explain what happened. BTW this had nothing to do with Ai.
yeah, sometimes it feels like the same people complaining about python speed are the ones writing “C” code in python.
The thing is also that you can’t separate a language from its ecosystem.
Because it is possible to write the fastest programs in C/C++ and Rust, folks that actually need the fastest performance will use these languages and will go around opening pull requests to fix performance problems in commonly-used libraries.
So, you do often end up with the most performant design anyways, just because the language itself is fast on paper.
I wrote a draft of a service that would take hours to complete. when I optimized it for multithreaded operation instead of taking hours it took around 60 seconds.
write software like you write research papers. first draft > second draft > final draft > publication
Counterpoint, I wrote a Python program that reads a load of JSON and runs regex searches over it. It was quite slow. Rewrote it in Rust as a straight 1:1 port, no algorithmic changes. 50x speedup.
I think you must have either done something very wrong or your Python program didn’t really do anything other than call Python built-ins that are actually written in C.
Did you use a profiler to find the bottlenecks? Did you try using cjson to speed up the json parsing? I would also avoid using the stdlib regex library too. It’s probably more of a convenience/reference implementation, not something to be intended for high performance. Maybe there’s a re2 wrapper for Python or a similar regex library in C with Python bindings.
Rewriting in Rust is fine, but good Python devs know how to find bottlenecks in their software and replace them with fast implementations. I’ve written plenty of performant Python code, it’s not very hard to profile and optimize. Usually the performant stuff is already written in C/C++ or Fortran anyway (numpy, PyQt, etc.)
Did you use a profiler to find the bottlenecks?
No. It was a simple enough program that there were no areas for improvement anyway. I also did not use a profiler for the Rust code.
good Python devs know how to find bottlenecks in their software and replace them with fast implementations
In my experience this is also a sweet sounding lie to make people feel ok with using Python. Yes in some case you make a big mistake and there’s a large bottleneck you can easily remove… Or your program has a nice small hotspot where it spends most of its time and you can just write that bit in C++ (AI is the obvious example).
But most programs are not like that. They’re more like MS Word. Slowness is evenly distributed through the code. There is no hotspot to remove.
As an example of this, look at Nicholas Nethercote’s excellent series of blogs on making the Rust compiler faster: https://nnethercote.github.io/
The “bottlenecks” they find result in 1% speedups.
If you didn’t use a profiler, then how can you be sure that the issue was Python and not something else? If the slowness really is evenly distributed through the code as you suggest, then a profiler would show that almost instantly and it’s very easy to do that in Python using cProfile.
On top of that, the Python standard library is built for convenience, not performance. The nature of it being a standard library means that the implementation has to be simple. fastregex uses LLVM and SIMD for example, that’s something that’s wildly impractical for the Python stdlib to support. In contrast, I have no idea what regex or JSON library you used for your Rust code, but if it were outside the stdlib, chances are high that it had much more leeway to optimize performance because it didn’t have all the other maintenance obligations that stdlib code needs to support.
All of this is just pure speculation on my part, but ultimately I’m trying to make a point that it is hard to say that the difference was caused by a language issue and not something else. There are lots of other things that could be contributing to this difference and you can’t really say for sure without meaningful diagnostics.
As an example of this, look at Nicholas Nethercote’s excellent series of blogs on making the Rust compiler faster: https://nnethercote.github.io/
The “bottlenecks” they find result in 1% speedups.
The kinds of software that you and I write on a daily basis is nothing compared to pieces of software that get millions of man-hours per year. Assuming you’re not Linus Torvalds or Ted Ts’o hiding behind a funny alias, of course. I don’t think anyone is suggesting that it’s a good idea to write a compiler in Python (outside of prototyping purposes perhaps) since it’s obviously not I/O bound, but if you and I are trying to optimize something we wrote ourselves, we’re more likely to be in the “nice small hotspot” domain you described, rather than the 1% bottleneck speedups discussed in the link you posted.
Very cool link though by the way, I look forward to reading as much of it as I can…
If you didn’t use a profiler, then how can you be sure that the issue was Python and not something else?
It was a relatively simple program and I am good at programming.
The point is, I put the same amount of effort into writing the same program in Python and Rust, and Rust was 50x faster. With AI, I don’t see any reason to use Python these days anyway. I never bought the productivity arguments before (Rust is easily as productive as Python), but with AI Rust is definitely more productive than Python because of the much stronger static checks.
It wasn’t a very wrong what I did in Python. I did the obvious thing. While I do not remember details, I remember it had something to do with adding items I think. But sadly I have not documented this issue, that’s on me. It was only noticeable for really huge files like 50MBytes json. Edit: Most weren’t this big, but it also combined over 100 Json files into one, so a search would search them all through and be able to save as a single file.
I mean, python has a very nice set of tools that run at C speed so it’s not crazy to think you can get good performance out of it.
As an OPS guy you know what really grinds my gears? Developers not paying attention to shit like this.
We have a job in production that is a powershell script calling a powershell script calling a java applet. Now you may already be thinking “what is this abomination?” And you’re right, but that java application is set to DEBUG. IN PRODUCTION. So every time it runs it generates 1gb of logs.
Do they fix it? No of course not because if it’s not broken don’t fix it. But Jesus Christ we have people developing without understanding fundamentals like “YOU DONT LEAVE DEBUG ON IN PRODUCTION”.
I don’t understand how this is even possible.
People are dumb
Has everyone forgotten the art of creating or using performance profiling tools
I was in a meeting with a senior software engineer, who makes a shit ton more than me. While sharing my screen he saw flame graph I had for one program I was working on. They asked “what is that?”, I was taken back, and said it’s for looking at which functions are taking more time. Then I was asked “where did you find it?” I was shell shocked, didn’t know how to answer that. Similar things have happened before where I taught them certain things, and they go “great find”, like dude, I didn’t find it just now. That’s basic knowledge if you work with database.
I am not even a developer hire, I’m self learned, and because the company doesn’t have many developers they gave me some of the tasks and I’m doing it because it’s more fun than my job responsibilities, and when I don’t have enough tasks.
Flame graphs have really only been a thing for the last decade or so. The free tooling for profiling code has been shitty and difficult to understand for most of my career. And most companies aren’t willing to pay for it if the product runs “good enough”. These days companies lock down their shit so tight that you can’t even install an unapproved app no matter how free or useful.
I think that’s true for many tools. Programming tools are the one thing that has most advancement because so many programmer are there to improve on them. And even if you don’t use it, not knowing about it completely makes it a bit odd. Although most tools I have used to make flamegraph were as easy as just running the program as a argument to another program that tracks the function calls.
Ive used them to help a lot in the past, but they often didnt give enough detail. Like I would know the area something was a problem, but pinpointing exactly what it was was still up to me, and would take some time. It worked but it could have been better.
Turns out there was a library you can add which adds that extra missing detail, and with that it was possible to highlight the exact issue. Wish id known about that sooner. That was on me though.
Noticeable speed? Sure. But I am so pissed if a fucking todo list app is a 100mb download and consumed 300mb memory when running, all because this fucker bundles and loads a whole browser engine to render itself.
I therefore do think tech stack matters as well.
I’d add that most of the time nobody actually measured anything. at work we inherit slow sites all the time and the first guess is always “the stack”, then you profile it and it’s one query running per item in a loop or something like that. I had the same with my own side project, was sure I needed a bigger server and after measuring the problem was somewhere else completely. measuring first is boring but it’s cheaper than any rewrite I guess
Profiling complex systems can be quite difficult. That said, I believe in the adage “Profile twice, optimize once.”, adapted from the old carpenters adage of “Measure twice, cut once.”
Slowness is rarely essential, but I can be far away from where you expect it.
That’s what Open Telemetry is for, honestly, specifically tracing. I’m in the process of adding tracing for all of our web handlers, http client calls, database transactions/individual queries, and asynchronous jobs. Should give us a pretty good view into the performance of the system, and allow us to monitor for things like performance regressions without any dedicated profiling needed (though we certainly could add additional profiling information through Otel down the road). Since I know you’re a Haskeller (recognize your handle), the
hs-opentelemetryecosystem is quite solid and has integrations with a lot of libraries in the wider ecosystem, likewai,persistent,postgresql-simple,conduit, and a bunch more. I haven’t needed to write too much of our own instrumentation, aside from our job system since that’s a bespoke system.Yeah we used hs-opentelemetry at my last paid position. The company was an MS shop, tho so we were using ODBC to connect to MS SQL Server which doesn’t have great in-process profiling. But, at least we could figure out what quer(y/ies) were running long and then we could use the MS tools to look at the plan and fiddle with that. It was also a small org, so it’s not like there was a lot of internal services in one flow – basically everything either stayed in the Web Yesod app or in the IVR app. All our profiling could have been instrumented process profiling instead of having to use otel at all.
So, I haven’t seen how easy/difficult it is to actually use otel across multiple internal service calls to satisfy one external request.
yeah that matches what I see, most of what we run at work is one app and one database, so the slow query log plus looking at the plan gets you like 90% of the way. I never really had the multi service case where otel pays off, I guess at some point it does, but for a small team it felt like a lot of plumbing to end up finding the same n+1 query lol
Software engineer and can confirm this is mostly the case. Adding a spinner or cute animation to placate users is way easier than solving fundamental issues. There are definitely teams out there that absolutely care about performance but mostly in large scale scenarios where an extra 10ms per record adds up to 3 extra hours to finish a batch.
What if the language has a bad design?
Then use it poorly and it’s a double negative.
Every method just returns an empty string. Runs fast as hell. Just don’t expect it to do anything.
If you think about it, this was also true in the 80s, but because the hardware sucked. Good thing we learned better design so we can have things like AI
I’d argue a combination of bad design and/or bad implementation, which i would consider different things.
It’s a difference that becomes more pronounced the larger the team grows.
A somewhat reasonable design can be absolutely destroyed by a poor implementation of that design
Yes and no. It’s not usually the fault of the programming language.
But programming languages have a unique ability: The design of the language itself can and will instill bad or good habits into the code of oneself. These languages are designed pretty deliberately, so those habits are a direct consequence of the design of a language. In fact, Sean Goedecke’s own C-to-Rust example makes this point implicitly: Cantrill’s port got faster not because the redesign was really clever, but because Rust’s borrow checker and standard library actively steered him toward a more cache friendly Binary tree. There are probably many more examples out there that had a real world impact.
There are no bad languages, every language has its place somewhere. But design decisions matter.
There are no bad languages
Malbolge. ;)
The title itself is provably wrong. Take the Matrix spec / protocol, install Synapse (written in Python) and watch your 16GB ram, 4 cors shit itself live under 0 load; or run tuwunel (written in Rust) and watch it using 100MB of RAM and a single core while handling a hundred users (Dendrite written in go was also great but it’s incomplete). Same for some Mastodon implementations, even Elixir wasn’t great and I was disappointed.
Now if you are building some ETL or a thin API wrapper, where the bottleneck is somewhere else like a DB or another API, then yes, don’t bother, Python would do.
I hate these kinds of comments that have no other purpose than to sling shit and start arguments.
Since this is a programming community (and giving you the benefit of the doubt, I assume you’re not a vibe coder), you know your argument is nonsense. Writing something in Python doesn’t automatically make it slow or use a lot of RAM or whatever. Synapse is shitty because Synapse is shitty. You can write slow and inefficient software in any language, and it feels really tedious to type this out because it’s obvious and common sense.
You can write slow and inefficient software in any language
Yes, but you can’t write snappy fast software in any language, high level languages like python, lua and php carry alot of overhead from the get go, because of dynamic typing, heavy abstractions, and heavy garbage collectors.
Your entire comment adds nothing, like 0 value. I provided two counter examples of verifiable, publicly available, familiar to tech people and programmers projects people can inspect now. Your comment doesn’t even bother to bring something real, an LLM could put together a better counter argument by actually inspecting the github repos.
Synapse is shitty
I get the feeling you are wasting everyone’s time and you have no idea what are you talking about. Show us your cooler projects?
I don’t think you’re making the kind of argument you intended to make. Those are two different programs with two different development teams behind them. The design behind them (the literal thing the article is talking about) are likely completely different from each other. Comparing the languages based on two different implementations of the same spec is a bit more than disingenuous. If you want to actually compare you need to recreate the same implementation as closely as feasible. Something like this https://youtu.be/WB7v-ezqcJM
Comparing the languages based on two different implementations of the same spec
I don’t think you realize how ridiculous this reads
Optimising too early is the root of all evil or something like that
Too many abstraction layers
deleted by creator
deleted by creator
I’ve been vibecoding pyqt based python apps lately. The performance even one of the so called “slowest” languages can do is more than fine. Not using Electron, or actually optimizing matter more than the language itself, most of the time anyway.
Python copium.











