Perhaps it is faster than already-existing implementations, sure, but not "faster than C", and it is odd to make such claims.
Perhaps it is faster than already-existing implementations, sure, but not "faster than C", and it is odd to make such claims.
I took 15 minutes to write one in Rust (a language I had just learned by that point) using a "that should work" approach and became second place, with some high effort C-implementations being slower and a highly optimized assembler variant taking first place.
Since then I programmed a lot more in C and C++ as well (for other reasons) and got more experience. Rust is not automatically faster, but the defaults and std library of Rust is so well put together that a common-sense approach will outperform most C code without even trying – and it does so while having typesafety and memory safety. This is not nothing in my book and still extremely impressive.
The best thing about learning Rust however was how much I learned for all the other languages. Because what you learn there is not just how to use Rust, but how to program well. Understanding the way the Rust borrow checker works 1000% helped me avoiding nasty bugs in C/C++ by realizing that I violatr ownership rules (e.g. by having multiple writers)
zlib-ng can be compiled to whatever target arch is necessary, and the original post doesn't mention how it was compiled and what architecture and so on.
It's another case not to trust micro benchmarks
I also wonder how much of an improvement you’d get by just asking for a “simple rewrite” in the existing language. I suspect there are often performance improvements to be had with simple changes in the existing language
5-15% is a big deal for a low-level foundational code, especially if you get it along with some other guarantees, which may be of greater importance.
As is the case with any languages, of course, it is not in favor (nor against) Rust.
Not necessarily—sometimes languages are especially poorly suited for tasks or difficult to hire for.
But yes you are technically correct, congratulations.
Obviously the code isn't going anywhere, and obviously we DO have reliable code we've built with C. But acting like C and Rust deliver equivalent value is simply farcical: you choose C for rapid development and cheap devs (or some other niche concern, like using an obscure embedded arch), and you choose rust to solve the problems that C introduced.
They hadn't expected any perf improvements at all. Quite the opposite, in fact. They were surprised that they saw perf improvements right away.
Furthermore, they said that they did not expect any performance gains. They did the rewrite for other reasons and got the unexpected bonus of extra performance.
For example, he says they didn’t set out to improve the code, but they were porting decennia-old C code to rust. Given the subject (truetype font parsing and rendering), my guess would be that the original code had more memory copies copying data out of the font data because rust makes it easier to safely avoid that (in which case the conclusion would be “C could be as fast, but with a lot more effort”), but it could also be that they spent a day figuring out some code did to realize that it wasn’t necessary on anything after Windows 95, and stripped it out, rather than porting it.
Yes, if your code in Lang-X is faster than C, it's almost certainly a skill issue somewhere in the C implementation.
However, in the day-to-day, if I can make my code run faster in Lang-X than C, especially if I'm using Lang-X for only a couple of months and C potentially for decades, that is absolutely meaningful. Sure, we can make the C code just as fast, but it's not viable to spend that much time and expertise on every small issue.
Outside of "which lang is better" discussions on online forums, it doesn't matter how fast you can theoretically make your program, it matters how fast you actually make it with the constraints your business have (time usually).
I'm always reminded of this video, where the author writes the same program in Rust and Go.
https://www.youtube.com/watch?v=Z0GX2mTUtfo
> Now, the Rust version took me about five times as long as the Go version
> The Go one performed almost identically well
Now this was for netcode rather than number crunching. But I actually had a similar surprise with number crunching, with C# and C++. I wrote the same program (rational approximation of Pi), line for line, in both languages, and the C# version ran faster. Apparently C# aggressively optimizes hot code paths while running, whereas to get that behavior in C++, you need to collect profiler data and use a special compiler flag.
I'm currently working with ~150 dependencies in my current project which I know would be a major hurdle in previous C or C++ projects.
For example, cargo-vet and cargo-crev allow you to rely on others you trust to help audit dependencies.
This is an interesting word. I wonder why no one has written high performance library code in assembly yet at this point?
What do you mean by that?
There is plenty of hand-rolled assembly in low-level libraries, whether you look at OpenBLAS (17%), GMP (36%), BoringSSL (25%), WolfSSL (14%) -- all of these numbers are based on looking at Github's language breakdown (which is measured on a per-file basis, so doesn't count inline asm or heavy use of intrinsics).
There are contexts where you want better performance guarantees than the compiler will give you. If you're dealing with cryptography, you probably want to guard against timing attacks via constant-time code. If you're dealing with math, maybe you really do want to eke out as much performance as possible, autovectorization just isn't doing what you want it to do, and your intrinsic-based code just isn't using all your registers as efficiently as you'd like.
The answer is that its more ergonomic and easier to reason about. So while you can TECHNICALLY have "algebraic data types" in C i.e. "its just a tagged union so whats the big deal?" I prefer to use them in Rust than C, for whatever unknown reason...
I also don't want to spend my brain cells thinking about pointer provenance and which void* aliases with each other. I would rather spend it on something else, thank you very much.
How do you know this exactly?
EDIT: but I do agree that starting greenfield from an old code base is often a path towards performance.
Typical realworld C code uses \0 terminated strings and strlen() with O(len^2) complexity.