Hacker News new | ask | show | jobs
by blundergoat 92 days ago
The real win here isn't TS over Rust, it's the O(N²) -> O(N) streaming fix via statement-level caching. That's a 3.3x improvement on its own, independent of language choice. The WASM boundary elimination is 2-4x, but the algorithmic fix is what actually matters for user-perceived latency during streaming. Title undersells the more interesting engineering imo.
10 comments

They even directly conclude at the end of the article that improvements in algorithm are more important than the choice of language:

> Algorithmic complexity improvements dominate language-level optimisations. Going from O(N²) to O(N) in the streaming case had a larger practical impact than switching from WASM to TypeScript.

Yet they still have chosen to put the “Rust rewrite” part in the title. I almost think it's a click bait.

Yeah the algorithmic fix is doing most of the work here. But call that parser hundreds of times on tiny streaming chunks and the WASM boundary cost per call adds up fast. Same thing would happen with C++ compiled to WASM.
O(N²) -> O(N) was 3.3x faster, but before that, eliminating the boundary (replacing wasm with JS) led to speedups of 2.2x, 4.6x, 3.0x (see one table back).

It looks like neither is the "real win". both the language and the algorithm made a big difference, as you can see in the first column in the last table - going to wasm was a big speedup, and improving the algorithm on top of that was another big speedup.

same for uv but no one takes that message. They just think "rust rulez!" and ignore that all of uv's benefits are algo, not lang.
Some architectures are made easier by the choice of implementation language.
UV also has the distinct advantage in dependency resolution that it didn't have to implement the backwards compatible stuff Pip does, I think Astral blogged on it. If I can find it, I'll edit the link in.

edit wasn't Astral, but here's the blog post I was thinking of. https://nesbitt.io/2025/12/26/how-uv-got-so-fast.html

That said, your point is very much correct, if you watch or read the Jane Street tech talk Astral gave, you can see how they really leveraged Rust for performance like turning Python version identifiers into u64s.

In my experience Rust typically makes it a little bit harder to write the most efficient algo actually.
That’s usually ok bc in most code your N is small and compiler optimizations dominate.
Would you be willing to give an example of this?
Not OP, but one example where it is a bit harder to do something in Rust that in C, C++, Zig, etc. is mutability on disjoint slices of an array. Rust offers a few utilities, like chunks_by, split_at, etc. but for certain data structures and algorithms it can be a bit annoying.

It's also worth noting that unsafe Rust != C, and you are still battling these rules. With enough experience you gain an understanding of these patterns and it goes away, and you also have these realy solid tools like Miri for finding undefined behavior, but it can be a bit of a hastle.

Has no one written a python! macro for this use case?
Mutating tree structures tends to be a fiddle (especially if you want parent pointers).
Just the fact that I can install a single binary is 10x better than an equally fast Python implementation.
That's a pretty big claim. I don't doubt that a lot of uv's benefits are algo. But everything? Considering that running non IO-bound native code should be an order of magnitude faster than python.
Its a pretty well-supported claim. uv skips doing a number of things that generate file I/O. File I/O is far more costly than the difference in raw computation. pip can't drop those for compatibility reasons.

https://nesbitt.io/2025/12/26/how-uv-got-so-fast.html

I don't think the article you linked supports the claim that none of UV performance improvements are related to using rust over python at all. In fact it directly states the exact opposite. They have an entire section dedicated to why using Rust has direct performance advantages for UV.
What it says is this:

> uv is fast because of what it doesn’t do, not because of what language it’s written in. The standards work of PEP 518, 517, 621, and 658 made fast package management possible. Dropping eggs, pip.conf, and permissive parsing made it achievable. Rust makes it a bit faster still.

Yes exactly! That quote directly disproves that all of the improvements UV has over competitors is because of algos, not because of rust.

So the claim is not well supported at all by the article as you stated, in fact the claim is literally disproven by the article.

Do you actually believe that UV would be as fast if it were written in Python?
It would come pretty close, probably close enough that you wouldn't be able to tell the difference on 90% of projects.
Vague. What's pretty close? I mean, even for IO bound tasks you can pretty quickly validate that the performance between languages is not close at all - 10 to 100x difference.
More than one, I'd think.
You’re not wrong, but that win would not get as many views. It’s not clickbaity enough
> The real win here isn't TS over Rust

Kinda is. We came up with abstractions to help reason about what really matters. The more you need to deal with auxillary stuff (allocations, lifetimes), more likely you will miss the big issue.

The opposite: the more you rely on abstractions the more you miss the lower level optimization opportunities and loose understanding of algorithms and hardware.
> of algorithms

Yes, sprinkling your code logic with malloc, .clone() or lifetime annotations on the other hand brings algorithmic enlightenment.

Dealing and having to think about the cost of malloc, clone() and lifetimes, brings algorithmic enlightenment more than working on an high abstraction ivory tower where things "magically happen".

Is your argument that the average Python or Typescript dev gets to think and care more about algorithms than the average C/C++/Rust dev?

Yeah, though the n^2 is overstating things.

One thing I noticed was that they time each call and then use a median. Sigh. In a browser. :/ With timing attack defenses build into the JS engine.

For those of us not in the know, what are we expecting the results of the defenses to be here?
Jitter. It make precise timings unreliable. Time the entire time of 1000 runs and divide by 1000 instead of starting and stopping 1000 timers.
No AI generated comments on HN please.
> Title undersells the more interesting engineering imo.

Thanks for cutting through the clickbait. The post is interesting, but I'm so tired of being unnecessarily clickbaited into reading articles.

More like a misleading clickbait.