One example where Rust enables better and faster abstractions is traits. C you can do this with some ugly methods like macros and such but in Rust it’s not the implementers choice it’s the callers choice whether to use dynamic dispatch (function pointer table in C) or static dispatch (direct function calls!)
In c the caller isn’t choosing typically. The author of some library or api decides this for you.
This turns out to be fairly significant in something like an embedded context where function pointers kill icache and rob cycles jumping through hoops. Say you want to bit bang a bus protocol using GPIO, in C with function pointers this adds maybe non trivial overhead and your abstraction is no longer (never was) free. Traits let the caller decide to monomorphize that code and get effectively register reads and writes inlined while still having an abstract interface to GPIO. This is excellent!
I think personally the answer is "basically no", Rust, C and C++ are all the same kind of low-level languages with the same kind of compiler backends and optimizations, any performance thing you could do in one you can basically do in the other two.
However, in the spirit of the question: someone mentioned the stricter aliasing rules, that one does come to mind on Rust's side over C/C++. On the other hand, signed integer overflow being UB would count for C/C++ (in general: all the UB in C/C++ not present in Rust is there for performance reasons).
Another thing I thought of in Rust and C++s favor is generics. For instance, in C, qsort() takes a function pointer for the comparison function, in Rust and C++, the standard library sorting functions are templated on the comparison function. This means it's much easier for the compiler to specialize the sorting function, inline the comparisons and optimize around it. I don't know if C compilers specialize qsort() based on comparison function this way. They might, but it's certainly a lot more to ask of the compiler, and I would argue there are probably many cases like this where C++ and Rust can outperform C because of their much more powerful facilities for specialization.
I almost ignored this post because I can't stand this particular war, where examples are cherry picked to prove either answer.
I'm very happy to see the nuanced take in this article, slowly deconstructing the implicit assumptions proposed by the person asking this question, to arrive at the same conclusion that I long have. I hope this post reaches the right people.
A particular language doesn't have a "speed", a particular implementation may have, and the language may have properties that make it difficult to make a fast implementation (of those specific properties/features) given the constraints of our current computer architectures. Even then, there's usually too many variables to make a generalized statement, and the question often presumes that performance is measured as total cpu time.
I like to say that there are two primary factors when we talk about how "fast" a language is:
1. What costs does the language actively inject into a program?
2. What optimizations does the language facilitate?
Most of the time, it's sufficient to just think about the first point. C and Rust are faster than Python and Javascript because the dynamic nature of the latter two requires implementations to inject runtime checks all over the place to enable that dynamism. Rust and C simply inject essentially zero active runtime checks, so membership in this club is easy to verify.
The second one is where we get bogged down, because drawing clean conclusions is complicated by the (possibly theoretical) existence of optimizing compilers that can leverage the optimizability inherent to the language, as well as the inherent fragility of such optimizations in practice. This is where we find ourselves saying things like "well Rust could have an advantage over C, since it frequently has more precise and comprehensive aliasing information to pass to the optimizer", though measuring this benefit is nontrivial and it's unclear how well LLVM is thoroughly utilizing this information at present. At the same time, the enormous observed gulf between Rust in release mode (where it's as fast as C) and Rust in debug mode (when it's as slow as Ruby) shows how important this consideration is; Rust would not have achieved C speeds if it did not carefully pick abstractions that were amenable to optimization.
It's easier to write faster code in a language with compile-time facilities such as C++ or Rust than in C. For example, doing this sort of platform-specific optimization in C is a nightmare https://github.com/vitaut/zmij/blob/91f07497a3f6e2fb3a9f999a... (likely impossible without an external pass to generate multiple lookup tables).
In general "Is programming language X faster than Y" is a meaningless question. It mostly comes down to specific implementations - specific compilers, interpreters, etc.
The only case where one language is likely to be inherently faster than another is when the other language is so high level or abstracted away from the processors it is going to run on that an optimizing compiler is going to have a hard time bridging that gap. It may take more work for an optimizing compiler to generate good code for one language than another, for example by having to recognize when aliasing doesn't exist, but again this is ultimately a matter of implementation not language.
The question is what do we mean by "a fast language"? We could mean it to be how fast the fastest code that a performance expert in that language, with no resource constraints, could write. Or, we can restrict it to "idiomatic" code. Or we can say that a fast language is the one where an average programmer is most likely to produce fast code with a given budget (in which case probably none of the languages mentioned here are among the fastest).
Assembly is not part of the C language in the sense that it's not in the ISO standard dialect, which is inapplicable to Rust.
Rust is a project that is rather more comparable to GCC than ISO C.
Huh. I expected two main advantages on Rust's side: usable multithreading (as mentioned) and stack allocation. For the latter, the ownership model makes it possible to stack-allocate things that you wouldn't dare put on the stack in either C or C++, thus saving malloc and free time as well as second-order effects from avoiding fragmentation.
Does Rust not do this for subtle reasons that I'm missing, or does it just not matter as much as I'd expect it to?
It's not binary. If you try hard enough, I bet you can make an argument that C is faster and you can make an argument that Rust is faster.
There is a set of programs that you can write in C and that are correct, that you cannot write in Rust without leaning into unsafe code. So if by "Rust" we mean "the safe subset of Rust", then this implies that there must be optimal algorithms that can be written in C but not in Rust.
On the other hand, Rust's ownership semantics are like rocket fuel for the compiler's understanding of aliasing. The inability of compilers to track aliasing precisely is a top inhibitor of load elimination in C compilers (so much so that C compiler writers lean into shady nonsense like strict aliasing, and even that doesn't buy very much precision). But a Rust compiler doesn't need to rely on shady imprecise nonsense. Therefore, there are surely algorithms that, if written in a straightforward way in both Rust and C, will be faster in Rust. I could even imagine there are algorithms for which it would be very unnatural to write the C code in a way that matches Rust's performance.
I'm purely speaking theoretically, I have no examples of either case. Just trying to provide my PL/compiler perspective
The article does not mention the possible additional optimisation opportunities that arise in Rust code due to stricter aliasing rules of references. But I don’t have an example in mind. Does anyone know of an example of it happening in real code?
While people can nitpick, the article is pretty clear that there isn't a single answer. Everything depends on how you constrain the problem. How much experience does the developer have? What time constraints are there? Is it idiomatic code? How maintainable is the code? You can write C with Rust-like safety checks or Rust with C-like unsafety.
When you can directly write assembly with either, comparing performance requires having some constraints.
For what it's worth, I think coding agents could provide a reasonable approximation of what "average" code looks like for a given language. If we benchmark that we'd have some indication of what the typical performance looks like for a given language.
> Some people have reported that, thanks to Rust’s checks, they are more willing to write code that’s a bit more dangerous than in the equivalent C (or C++)
I rewrote a C project in Rust some years ago, and in the Rust version I included many optimizations that I probably wouldn't have in C code, thanks to the ability to do them "fearlessly". The end result was so much more performant I had to double check I didn't leave something out!
To answer the headline: No. Rust is not faster than C. C isn't faster than Rust either.
What is fast is writing code with zero abstractions or zero cost abstractions, and if you can't do that (because writing assembly sucks), get as close as possible.
Each layer you pile on adds abstraction. I've never had issues optimizing and profiling C code -- the tooling is excellent and the optimizations make sense. Get into Rust profiling and opimization and you're already in the weeds.
Want it fast? Turn off the runtime checks by calling unsafe code. From there, you can hope and pray like with most LLVM compiled languages.
If you want a stupid fast interpreter in C, you do computed goto, write a comment explaining why its not, in fact, cursed, and you're done. In C++, Rust, etc. you'll sit there examining the generated code to see if the heuristics detected something that ends up not generating effectively-computed-goto-code.
Not to mention panics, which are needed but also have branching overhead.
The only thing that is faster in Rust by default is probably math: You have so many more errors and warnings which avoid overflows, casts, etc. that you didn't mean to do. That makes a small difference.
I love Rust. If I want pure speed, I write unsafe Rust, not C. But it's not going to be as fast as trivial C code by default, because the tradeoffs fundamentally differ: Rust is safe by default, and C is efficient by default.
The article makes some of the same points but it doesn't read like the author has spent weeks in a profiler combing over machine code to optimize Rust code. Sadly I have, and I'm not getting that time back.
One bit I'm surprised isn't mentioned is Rust's "Zero Cost Abstractions" where this can vary a lot in C/C++ where the similar efforts at a given pattern may be dramatically different than Rust's default selection. Even in Rust there will often be other options that are relatively easy to use but could have dramatic differences in performance for a specific use case.
These variances pretty much mean that trying to compare with other "low level" languages is far from an apples to apples comparison.
So, to answer the question, "It depends." ... In the end, I think developers tend to optimize for a preferred style or ergonomics over hard technical reasons... it's mostly opinion, IMO.
Aren't there any scenarios where a C compiler (without assistance by the developer) must be defensive about aliasing, in a way that the Rust compiler must not be?
I guess you could argue that C would reach the same speed because noalias is part of C as well. But I'd say that the interesting competition is for how fast idiomatic and "hand-optimized" (no unrolling, no aliasing hints etc) code is.
Comparing programming languages "performance" only makes sense if comparing idiomatic code. But you could argue that noalias in C is idiomatic. But you could equally well argue that multi threading in Rust is more idiomatic than it is in C and so on. That's where it becomes interesting (and difficult) to quantify.
I know which one is faster to produce an unintended segfault.
Well, if we define a reasonable yardstick for this, and try to write idiomatic code without low-level hacks and optimization, Rust has the potential to be faster because its more strict aliasing rules might enable optimizations that the C compiler wouldn't try.
However I remember reading a few years back that due to the Rust frontend not communicating these opportunities to LLVM, and LLVM not being designed to take advantage of them, the real-world gains do not always materialize.
Also sometimes people write code in Rust that does not compile under the borrow checker rules, and alleviate this issue either by cloning objects or using RefCell, both of which have a runtime cost.
I feel like another optimization that rust code can exploit is uninhabited types. When combined with generics and sum types these can lead to entire branches being unreachable at the type level. Like Option<!> or Result<T, !>, rust hasn't stablized !, but you can declare them other ways such as an empty enum with no variants.
struct field alignment/padding isn't part of the C spec iirc (at least not in the way mentioned in the article), but it's almost always done that way, which is important for having a stable abi
also, if performance is critical to you, profile stuff and compare outputted assembly, more often than not you'll find that llvm just outputs the same thing in both cases
Is there a common pattern for "Is language X faster than language Y" ? Like what is your definition of faster : faster to developer, to start, to execute, to handle different workload with the same binaries (like JIT).
Interesting post, but read it for the journey, not the destination[0].
[0] tldr: "I think that there are so many variables that it is difficult to draw generalized conclusions."
I think the only reasonable way to interpret this question is "is Rust written by reasonably competent Rust developer spending a reasonable amount of time faster/slower than an equally competent C developer spending the same amount of time".
I don't think a language should count as "fast" if it takes an expert or an inordinate amount of time to get good performance, because most code won't have that.
So on those grounds I would say Rust probably is faster than C, because it makes it much much easier to use multithreading and more optimised libraries. For example a lot of C code uses linked lists because they're easy to write in C, even when a vector would be faster and more appropriate. Multithreading can just be a one line change in Rust.
That article did not contribute anything to the answer of the question quoted.
“It’s the memory, stupid!” So wrote Richard Sites, lead designer of the famous DEC Alpha chip, in 1996 (http://cva.stanford.edu/classes/cs99s/papers/architects_look...). It’s rung true for 30 years.
Where C application code often suffers, but by no means always, is the use of memory for data structures. A nice big chunk of static memory will make a function fast, but I’ve seen many C routines malloc memory, do a strcpy, compute a bit, and free it at the end, over and over, because there’s no convenient place to retain the state. There are no vectors, no hash maps, no crates.io and cargo to add a well-optimized data structure library.
It is for this reason I believe that Rust, and C++, have an advantage over C when it comes to writing fast code, because it’s much easier to drop in a good data structure. To a certain extent I think C++ has an advantage over Rust due to easier and better control over layout.
This post might get the record for people responding to the title without reading the article. Jeez people, it takes five seconds to discover that it subverts expectations.
Haha, I'm touting my own ten year old horn: https://news.ycombinator.com/item?id=12749717 Also see steveklabnik's comments. They are relevant.
Back then the C implementation of the (i.e., "one") micro benchmark beat the Rust implementation. I could squeeze out more performance by precisely controlling the loop unrolling. Nowadays, I don't really care and operate under the assumption that "Python is faster than $X and if it is not, it is still fast enough!"
As long as you can get the Rust code to compile it's about the same speed. The issue is that rustc is only available on limited platforms (and indeed lack of rustc has killed off entire hardware architectures in popular distros in a bit of tail wagging the dog), rustc changes in breaking ways (adding new features) every 3 months, current rust culture is all bleeding edge types so any rust code you encounter in the wild will require curl rust.up | sh rather than being able to use the 1 year old rust toolchain from your repos.
What good is speed if you cannot compile? c has both. Maybe in another decade rust will have settled down but now wrangling all the incompatible rust versions makes c the far better option. And no, setting cargo versions doesn't fix this. It's not something you'd run into writing rust code within a company but it's definitely something you run into trying to compile other people's rust code.
The real question at the core of any production: What's the minimum performance cost we can pay for abstractions that substantially boost development efficiency and maintainability? Just like in other engineering fields, the product tuned to yield the absolute maximum possible value in one attribute makes crippling sacrifices along other axes.
Sorry, maybe stupid question. But can't this be decided by some benchmarks, using some of the features in the article that purport to make Rust faster?
> Mozilla tried to parallelize Firefox’s style layout twice in C++, and both times the project failed. The multithreading was too tricky to get right.
That is a damn good reason to choose Rust over C++, even if the Rust implementation of the "same" thing should be a bit slower.
no way bruv.
One thing I’ve seen MANY times in C that isn’t an issue in rust, is people using slow linked lists because writing a proper btree or hash map takes substantially more effort.
>If we assume C is the ‘fastest language,’ whatever that means
I agree that it has no meaning. Speed(language) is undefined, therefore there is no faster language.
I get this often because python is referred to as a slow language, but since a python programmer can write more features than a C programmer in the same time, at least in my space, it causes faster programs in python, because some of those features are optimizations.
Now speed(program(language,programmer)) is defined, and you could do an experiment by having programmers of different languages write the same program and compare its execution times.
Betteridge's law of headlines already has an answer to that one.
tl;dr: Rust officially allows you to write inline assembly so it's fast, but in C it's not officially specified as part of the language. Plus more points which do not actually indicate Rust is faster than C.
... well, that's what I get for reading an article with a silly title.
TLDR: No.
Betteridge's Law of Headlines, saved you a click.
[flagged]
Off-topic: Is it just me, or have there been a disproportionally high number of ~mid 2025 posts that have been reposted the last few days?
It depends on a lot. If you need to go fast, look to assembly.
Depends what you're doing with it... You can make any language you want slower than another language by using it badly
In short, the maximum possible speed is the same (+/- some nitpicks), but there can be significant differences in typical code, and it's hard to define what's a realistic typical example.
The big one is multi-threading. In Rust, whether you use threads or not, all globals must be thread-safe, and the borrow checker requires memory access to be shared XOR mutable. When writing single-threaded code takes 90% of effort of writing multi-threaded one, Rust programmers may as well sprinkle threads all over the place regardless whether that's a 16x improvement or 1.5x improvement. In C, the cost/benefit analysis is different. Even just spawning a thread is going to make somebody complain that they can't build the code on their platform due to C11/pthread/openmp. Risk of having to debug heisenbugs means that code typically won't be made multi-threaded unless really necessary, and even then preferably kept to simple cases or very coarse-grained splits.