16 ms·
Is Rust faster than C?
- otikik 9mo agoI know which one is faster to produce an unintended segfault.
- deleted 9mo ago[deleted]
- gignico 9mo agoThe 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?
- bluGill 9mo agoMany C programs are vailid C++ and are faster when compiled with a C++ compiler because of those stricter aliasing and type rules. Like you though I have no examples.
- _qib3 9mo agoThat seems very odd - if it's possible to make those optimisations without any additional type data then why wouldn't GCC do that anyway? The benefit of stricter type rules is that more information is available to the compiler. Using a different compiler doesn't inherently increase the amount of type information.
- tcfhgj 9mo agotheoretically the C++ compiler needs to consider things like exceptions which don't exist in C, so I'd even tend to the opposite
- aw1621107 9mo agoI believe the claim is more precisely stated as "Many C programs are valid C++ and are faster when compiled as C++" - i.e., even though the text of the program didn't change, the rules for interpreting that text changed, and it's that difference in interpretation that permits better optimizations.
- teo_zero 9mo agoInteresting concept! Any examples?
- pornel 9mo agoWhen the optimizer knows writes can't change the reads, it can reorder and coalesce them. The main benefit of that is enabling autovectorization in more cases. Otherwise it saves a few loads here and there.
- steveklabnik 9mo agoIn the spirit of the article... there's a few ways in which this could go :) The first is, we do have some amount of empirical evidence here: Rust had to turn its aliasing optimizations on and off again a few times due to bugs in LLVM. A comment from 2021: https://github.com/rust-lang/rust/issues/54878#issuecomment-767151730 https://github.com/rust-lang/rust/issues/54878#issuecomment-... > When noalias annotations were first disabled in 2015 it resulted in between 0-5% increased runtime in various benchmarks. This leaves us with a few relevant questions: Were those benchmarks representative of real world code? (They're not linked, so we cannot know. The author is reliable, as far as I'm concerned, but we have no way to verify this off-hand comment directly, I link to it specifically because I'd take the author at their word. They do not make any claim about this, specifically.) Those benchmarks are for Rust code with optimizations turned off and back on again, not Rust code vs C code. Does that make this a good benchmark of the question, or a bad one? These were llvm's 'noalias' markers, which were written for `restrict` in C. Do those semantics actually take full advantage of Rust's aliasing model, or not? Could a compiler which implements these optimizations in a different way do better? (I'm actually not fully sure of the latest here, and I suspect some corners would be relying on the stacked borrows vs tree borrows stuff being finalized)
- Measter 9mo agoAnother issue we have to consider here for the measurements taken then is that it was miscompiling, which, to me, calls into question how much we can trust that performance change. Additionally, it was 10 years ago and LLVM has changed. It could be that LLVM does better now, or it could do worse. I would actually be interested in seeing some benchmarks with modern rustc.
- Karliss 9mo agoNot exactly real world, but real code example demonstrating strict aliasing rule in action for C++. https://godbolt.org/z/WvMb34Kea https://godbolt.org/z/WvMb34Kea Rust should have even more opportunities of this due to restrictions it has for writable references. There are 2 main differences between versions with and without strict aliasing. Without strict aliasing compiler can't assume that the result accumulator doesn't change during the loop and it has to repeatedly read/write it each iteration. With strict aliasing it can just read it to register, do the looping and write the result back at the end once. Second effect is that with strict aliasing enabled compiler can vectorize the loop processing 4 floats at the same time, most likely the same uncertainty of counter prevents vecotorization without strict aliasing. If you want something slightly simpler example you can disable vectorization by adding '-fno-tree-vectorize'. With it disabled there is still difference in handling of counter. Using restrict pointers and multiple same type input arrays it would probably be possible to make something closer to real world example.
- steveklabnik 9mo agoNote that Rust does not do strict aliasing, its model is different. Also note that C++ does not have restrict, formally speaking, though it is a common compiler extension. It's a C feature only!
- Tuna-Fish 9mo agoI believe this advantage is currently mostly theoretical, as the code ultimately gets compiled with LLVM which does not fully utilize all the additional optimization opportunities.
- adgjlsfhk1 9mo agoLLVM doesn't fully utilize all the power, but it does use an increasing amount every year. Flang and Rust have both given LLVM plenty of example code and a fair number of contributors who want to make LLVM work better for them.
- senko 9mo agoInteresting 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."
- taminka 9mo agostruct 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
- ajross 9mo ago> struct field alignment/padding isn't part of the C spec iirc It's part of the ABI spec. It's true that C evolved in an ad hoc way and so the formal rigor got spread around to a bunch of different stakeholders. It's not true that C is a lawless wasteland where all behavior is subject to capricious and random whims, which is an attitude I see a lot in some communities. People write low level software to deal with memory layout and alignment every day in C, have for fourty years, and aren't stopping any time soon.
- cyco130 9mo agoIt is indeed part of the standard. It says "Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared"[1] which doesn't allow implementations to reorder fields, at least according to my understanding. [1] https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf section 6.7.3.2, paragraph 17.
- taminka 9mo agoi was talking abt padding/alignment, not ordering, that's indeed not allowed you're right
- steveklabnik 9mo agoHere's the draft of C23: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf See "6.7.3.2 Structure and union specifiers", paragraph 16 & 17: > Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner appropriate to its type. > Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared.
- qsera 9mo ago[flagged]
- einpoklum 9mo agotl;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.
- steveklabnik 9mo agoThat’s not how I would summarize what I wrote, for what it’s worth. My summary would be “the question is malformed, you need to first state what the boundaries are for comparison before you can make any conclusions.” I think this is an interesting thing to discuss because many people assume that the answer to “is x faster than C?” to be “no” for all values of X.
- bigfishrunning 9mo ago> many people assume that the answer to “is x faster than C?” to be “no” for all values of X. This is because C does so little for you -- bounds checking must be done explicitly for instance, like you mention in the article, so C is "faster" unless you work around rust's bounds checking. It reminds me of some West Virginia residents I know who are very proud of how low their taxes are -- the roads are falling apart, but the taxes are very low! C is this way too. C is pretty optimally fast in the trivial case, but once you add bounds checking and error handling and memory management its edge is much much smaller (for Rust and Zig and other lowish-level languages)
- bluGill 9mo agoIn the real world the difference is rarely significant assuming great programmings implement great algorithms. However those two assumptions are rarely true.
- sevensor 9mo agoI read the post to see how you would answer, not because I was unclear about what the answer would be, because the only possible answer here is “sometimes.” I especially like the point that Rust can be faster because it enables you to write different things. As I never tire of getting downvoted for saying, I’ve improved the speed of a program by replacing C with Python, because nobody could figure out how to write the right thing in C. If even Python can do this, it must apply to just about every pair of languages.
- voidUpdate 9mo agoDepends what you're doing with it... You can make any language you want slower than another language by using it badly
- philipallstar 9mo agoThis is like saying that no car is faster than any other because it depends what gear you drive it in
- voidUpdate 9mo agoThat's true as well. Language speed depends on how you use it
- philipallstar 9mo agoIt's true but incomplete.
- AlanLan 9mo agoIt’s a bit more fundamental than just "using it badly." The real tension lies in whether a language's safety invariants force a memory layout that is inherently at odds with the CPU cache hierarchy. In low-latency systems, the true "tax" is often the loss of determinism. If I have to sacrifice a cache-friendly structure or introduce indirection just to satisfy a borrow checker's static analysis, the performance game is already lost, regardless of how "well" I use the language. To give a concrete example: I previously built a high-frequency bridge for MT4 using a strict Modern C++ stack. I observed that after the initial warm-up, the working set actually settled from 13.6MB down to a stable 11.0MB and stayed there for a 7-day continuous stress test. This 2.6MB drop was simply the OS reclaiming initialization overhead—a result of manual memory management (via custom pool allocators) preventing heap fragmentation from "pinning" that memory. You don't achieve that level of long-term residency stability by just "using a language well"; you get it by using a toolchain that allows you to treat the hardware as the ultimate source of truth.
- deleted 9mo ago[deleted]
- bfrog 9mo agoOne 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!
- K0nserv 9mo ago> In c the callers isn’t choosing typically. The author of some library or api decides this for you. Tbf this applies to Rust too. If the author writes fn foo(bar: Box<dyn BarTrait>) they have forced the caller into dynamic dispatch. Had they written fn foo(bar: impl BarTrait) the choice would've remained open to the caller
- nicoburns 9mo agoRight, but almost all APIs in Rust use something like fn foo(bar: impl BarTrait) and AFAIK it isn't possible to write that in C (though C++ does allow this kind of thing).
- bfrog 9mo agoC++ you either use templates or classes and virtuals. In either case the caller doesn't get to decide.
- Seattle3503 9mo agoInteresting, there isn't some way to have a template that is polymorphic over virtuals?
- pron 9mo agoThe 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).
- justin66 9mo agoThese are the languages an "average programmer" would use. What language are you thinking of?
- pron 9mo agoI may be biased, but I think that if you have a budget that's reasonable in the industry for some project size and includes not only the initial development but also maintenance and evolution over the software's lifetime, especially when it's not small (say over 200KLOC), and you want to choose the language that would give you the fastest outcome, you will not get a faster program than if you chose Java. To get a faster program in any language, if possible, would require a significantly higher budget (especially for the maintenance and evolution).
- cdelsolar 9mo agoGo?
- pron 9mo agoI don't think so, but it may not be far behind. More importantly, though, I'm fairly confident it won't be Assembly, or C, or C++, or Rust, or Zig, but also not Python, or TS/JS. The candidates would most likely include Java, C#, and Go.
- xnorswap 9mo agoDo you think C# / .NET doesn't stack up in terms of budget, or not stack up in terms of runtime speed?
- hobofan 9mo agoOff-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?
- tycoon666 9mo agoNo.
- steveklabnik 9mo agoI love Betteridge's Law, and so one small thing I was trying to do here was subvert it a bit. Instead of "no," in this case, the answer is "the question is malformed."
- jonstewart 9mo ago“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_to_future.pdf 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.
- JacoboJacobi 9mo agoI'd certainly agree that malloc is the Achilles heel of any real world C. Overall though C++ was not a particularly good solution to memory efficiency since having OO available made the situation look like a fast sprint to the cake shop.
- jonstewart 9mo agoHeavy smalltalk-style OOP in C++ has kind of died out, especially with data structures. So with any templated data structure you’re reducing indirection from vtables and you have the opportunity to allocate however you want, often in continuous slabs to ease memory transfer and caching.
- kibwen 9mo agoI 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.
- bluGill 9mo agoIs Javascript significantly slower? It is extremely common in the real world and so a lot of effort has gone into optimizing it - v8 is very good. Yes C and Rust enable more optimizations: they will be slightly faster, but javascript has had a lot of effort put into making it run fast.
- sgeisenh 9mo agoYes, for most real-world examples JavaScript is significantly slower; JIT isn’t free and can be very sensitive to small code changes, you also have to consider the garbage collector. Speed is also not the only metric, Rust and C enable much better control over memory usage. In general, it is easier to write a memory-efficient program in Rust or C than it is in JS.
- 9mo ago
- classified 9mo ago> 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.
- bluGill 9mo agoOnly if it is repeatable. We have no information on what they learned in the two failed attempts - it is likely that they learned from the failures and started other architectural changes that enabled the final one to work. As such we cannot say anything about this. Rust does have some interesting features, which restrict what you are allowed to do and thus make some things impossible but in turn make other things easier. It is highly likely that those restrictions are part of what made this possible. Given infinite resources (which you never have) a C++ implementation could be faster because it has better shared data concepts - but those same shared data concepts make it extremely hard to reason about multi-threaded code and so humanly you might not be able to make it work.
- steveklabnik 9mo agoWe do have some information: https://youtu.be/Y6SSTRr2mFU?t=361 https://youtu.be/Y6SSTRr2mFU?t=361 (linked with the specific timestamp) In short, the previous two attempts were done by completely different groups of different people, a few years apart. Your direct question about if direct wisdom from these two attempts was shared, either between them, or used by Stylo, isn't specifically discussed though. > a C++ implementation could be faster because it has better shared data concepts What concepts are those?
- bluGill 9mo ago> What concepts are those? Data can be modified by any thread that wants to. It is up to you to ensure that modifications work correctly without race conditions. In rust you can't do this (unsafe aside), the borrow checker enforces data access patterns that can't be proved correct. Again let me be clear: the things rust doesn't allow are hard to get correct.
- IshKebab 9mo agoI 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.
- oguz-ismail2 9mo agoSo assembly is the slowest language?
- hmry 9mo agoDepends. If it takes an assembly programmer 8 hours to implement <X>, can an equally proficient Python programmer spending 8 hours to implement <X> create a faster program? Let's say they only need 2 hours to get the <X> to work, and can use the remaining 6 hours for optimizing. Can 6 hours of optimizing a Python program make it faster than the assembly program? The answer isn't obvious, and certainly depends on the specific <X>. I can imagine various <X> where even unlimited time spent optimizing Python code won't produce faster results than the assembly code, unless you drop into C/C++/Zig/Rust/D and write a native Python extension (and of course, at that point you're not comparing against Python, but that native language).
- IshKebab 9mo agoMaybe it's best to think of it as an effort-performance graph. For a given amount of effort what performance do you get? Assembly is going to give you pretty great performance generally, but the line only starts when you get to "ridiculous effort"!
- kstrauser 9mo agoOr honestly, anything involving a hashmap. Of course you can write those in C, but it’s enough friction that most people won’t for minor things. In Rust, it’s trivial, so people are more likely to use them.
- OskarS 9mo agoI 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.
- renox 9mo ago>signed integer overflow being UB would count for C/C++ Then, I raise you to Zig which has unsigned integer overflow being UB.
- steveklabnik 9mo agoInterestingly enough, Zig does not use the same terminology as C/C++/Rust do here. Zig has "illegal behavior," which is either "safety checked" or "unchecked." Unchecked illegal behavior is like undefined behavior. Compiler flags and in-source annotations can change the semantics from checked to unchecked or vice versa. Anyway that's a long way of saying that you're right, integer overflow is illegal behavior, I just think it's interesting.
- ladyanita22 9mo agoRust has UB overflow as well, just unsafe. https://doc.rust-lang.org/std/intrinsics/fn.unchecked_add.html https://doc.rust-lang.org/std/intrinsics/fn.unchecked_add.ht...
- mid-kid 9mo agoI 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.
- steveklabnik 9mo agoI will admit the title was a bit of a gamble, but thank you for taking the time to read it and I'm glad that you enjoyed it in the end.
- jibal 9mo agoWe recently had a post here where the claim being refuted was in quotes in the title, but half the comments were as if the article were making the claim, clearly indicating that people didn't read it (and don't understand how quote marks work).
- steveklabnik 9mo agoYes, this is an age old problem, for sure. It's a good thing to keep in mind when you read the comments on any article.
- aw1621107 9mo agoAssuming I'm thinking of the same submission as you, the quotes were not present in the original submission [0]. [0]: https://news.ycombinator.com/item?id=46525937 https://news.ycombinator.com/item?id=46525937
- effnorwood 9mo agoIt depends on a lot. If you need to go fast, look to assembly.
- HarHarVeryFunny 9mo agoAs I just posted, any speed comparison needs to be based on specific implementations (compiler A vs compiler B), not languages. When it comes to assembly, the "compiler" is the person writing the code, and while assembly gives you the maximum flexibility to potentially equal or outperform any compiler for any language, there are not too many people with the skill to do that, especially when writing large programs (which due to the effort required are rarely written in assembler). In general there is much more potential for improving the speed of programs by changing the design and using better algorithms, which is where high level languages offer a big benefit by making this easier.
- ndiddy 9mo agoIt depends on what you're writing and what the scope is. Here's a good quote about this from Steve Yegge, from his time working at Geoworks (company that did an entire desktop OS written entirely in 8086 assembly as a competitor to Windows for low-end PCs). https://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html https://steve-yegge.blogspot.com/2008/05/dynamic-languages-s... > I went to the University of Washington and [then] I got hired by this company called Geoworks, doing assembly-language programming, and I did it for five years. To us, the Geoworkers, we wrote a whole operating system, the libraries, drivers, apps, you know: a desktop operating system in assembly. 8086 assembly! It wasn't even good assembly! We had four registers! [Plus the] si [register] if you counted, you know, if you counted 386, right? It was horrible. > I mean, actually we kind of liked it. It was Object-Oriented Assembly. It's amazing what you can talk yourself into liking, which is the real irony of all this. And to us, C++ was the ultimate in Roman decadence. I mean, it was equivalent to going and vomiting so you could eat more. They had IF! We had jump CX zero! Right? They had "Objects". Well we did too, but I mean they had syntax for it, right? I mean it was all just such weeniness. And we knew that we could outperform any compiler out there because at the time, we could! > The problem is, picture an ant walking across your garage floor, trying to make a straight line of it. It ain't gonna make a straight line. And you know this because you have perspective. You can see the ant walking around, going hee hee hee, look at him locally optimize for that rock, and now he's going off this way, right? > This is what we were, when we were writing this giant assembly-language system. Because what happened was, Microsoft eventually released a platform for mobile devices that was much faster than ours. OK? And I started going in with my debugger, going, what? What is up with this? This rendering is just really slow, it's like sluggish, you know. And I went in and found out that some title bar was getting rendered 140 times every time you refreshed the screen. It wasn't just the title bar. Everything was getting called multiple times. > Because we couldn't see how the system worked anymore! > Small systems are not only easier to optimize, they're possible to optimize. And I mean globally optimize.
- pornel 9mo agoIn 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.
- OptionOfT 9mo agoApart from multi threading, there is more information in the Rust type system. Would that would allow more optimizations?
- adgjlsfhk1 9mo agoYes. Specifically since Rust's design prevents shared mutablity, if you have 2 mutable data-structures you know that they don't alias which makes auto vectorization a whole lot easier.
- kouteiheika 9mo agoYes. All `&mut` references in Rust are equivalent to C's `restrict` qualified pointers. In the past I measured a ~15% real world performance improvement in one of my projects due to this (rustc has/had a flag where you can turn this on/off; it was disabled by default for quite some time due to codegen bugs in LLVM).
- steveklabnik 9mo agoNot just all &mut T, but also all &T, where the T does not transitively contain an UnsafeCell<T>. Click "show llvm ir" instead of "build" here: https://play.rust-lang.org/?version=stable&mode=release&edition=2024&gist=34cca2d4f7dbaf1d4ef5d9ef1c3e7d3b https://play.rust-lang.org/?version=stable&mode=release&edit...
- TZubiri 9mo ago>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.
- deleted 9mo ago[deleted]
- jryb 9mo agoThis 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.
- bjourne 9mo agoHaha, I'm touting my own ten year old horn: https://news.ycombinator.com/item?id=12749717 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!"
- ratmice 9mo agoI 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.
- kawogi 9mo agoIn your specific example `std::convert::Infallible` can be used: https://doc.rust-lang.org/std/convert/enum.Infallible.html https://doc.rust-lang.org/std/convert/enum.Infallible.html
- ratmice 9mo agoSure, in the Result case, less in the option case. I didn't mention it because Infallible is documented and named specifically as an Error "The error type for errors that can never happen". The use of uninhabited types as an unreachable code optimization is useful beyond errors though.
- HarHarVeryFunny 9mo agoIn 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.
- gpderetta 9mo agoLanguage design still has a huge impact on which optimizations are practically implementable. The Mythical Sufficiently Smart Compiler is, in fact, still mythical.
- HarHarVeryFunny 9mo agoSure, but not all compilers are created equal and are going to go to the same lengths of analysis to discover optimization opportunities, or to have the same quality of code generation for that matter. It might be interesting to compare LLVM generated code (at same/maximum optimization level) for Rust vs C, which would remove optimizer LOE as a factor and more isolate difficulties/opportunities caused by the respective languages.
- mgaunard 9mo agoBetteridge's law of headlines already has an answer to that one.
- steveklabnik 9mo agoYes, I'm deliberately trying to evoke it to subvert it, see here: https://news.ycombinator.com/item?id=46616037 https://news.ycombinator.com/item?id=46616037
- farnulfo 9mo agoIs 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).
- sfink 9mo agoYes. "Is language X faster than language Y?" means "Is language X better than language Y?", which means "Do you like language X more than you like language Y?", which means "Do you have more experience with language X than language Y?" (well, good experiences, I guess). So "Is language X faster than language Y?" is totally answerable, but the answer depends on the answerer.
- uwagar 9mo agono way bruv.
- torginus 9mo agoWell, 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.
- FrustratedMonky 9mo agoSorry, 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?
- steveklabnik 9mo agoNot a stupid question :) Part of what I'm getting at here is that you have to decide what is in those benchmarks in the first place. Yes, benchmarks would be an important part of answering this question, but it's not just one question: it's a bunch of related but different questions.
- NetMageSCW 9mo agoThat article did not contribute anything to the answer of the question quoted.
- sfink 9mo agoIt did not contribute to a yes/no answer, which is good, because it is not answerable with "yes" or "no", and the article points that out and explains why. So I would disagree; it does contribute to answering the question, in the form of spelling out why it is unanswerable. Compare: "Have you stopped beating your wife yet?" "I do not beat my wife." The response contributes to the answer, even if it brings you no closer to "yes" or "no".
- rvz 9mo agoTLDR: No. Betteridge's Law of Headlines, saved you a click.
- netbioserror 9mo agoThe 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.
- lionkor 9mo agoTo 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.
- steveklabnik 9mo ago> Want it fast? Turn off the runtime checks by calling unsafe code. You can do that for sure, but you can also sometimes write your code in a different way. https://davidlattimore.github.io/posts/2025/09/02/rustforge-wild-performance-tricks.html https://davidlattimore.github.io/posts/2025/09/02/rustforge-... is an interesting collection of these. > it doesn't read like the author has spent weeks in a profiler combing over machine code to optimize Rust code It is true that this blog post was not intended to be a comprehensive comparison of the ways in which Rust and C differ in performance. It was meant to be a higher level discussion on the nature of the question itself, using a few examples to try and draw out interesting aspects of that comparison.
- michalsustr 9mo ago
- pizlonator 9mo agoIt'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
- School-Cotton 9mo ago> 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" Well, unsafe rust is part of rust. So no, we don’t mean that.
- vlovich123 9mo agoIf programs were primarily unsafe rust, no one would use the language. Unsafe rust is strictly more difficult to write than C in certain constructs because the complex invariants the rust language requires remain in unsafe, there’s just no compiler proof checking them being upheld. Is argue that he’s right that generally it’s referring to safe subset and in practice people relax the conversation with a little unsafe being more ok. But as Steve points out it really depends on the definitions you choose.
- School-Cotton 9mo agoOne 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.
- jkarneges 9mo ago> 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!
- shmolyneaux 9mo agoWhile 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.
- steveklabnik 9mo agoThank you. I wrote this at a time when I was pretty anti-LLM, but I do think that you're right that there's some interesting implications of LLM usage in this space. And that's because one version of this question is "what can the average x programmer do compared to the average y programmer in the same amount of time," and I'm curious if LLMs lift all tides here, or not.
- alkonaut 9mo agoAren'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.
- steveklabnik 9mo agoYes. Your point about noalias (the keyword is 'restrict' in C, noalias is the LLVM IR annotation) is right. What I will say is that the fact that Rust uses this so much, and had to turn it off because of all the bugs it shook out, at least implies that it's not used very much in real-world C code. I don't know how to more scientifically analyze that, though.
- tracker1 9mo agoOne 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.
- superkuh 9mo agoAs 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.
- junon 9mo agoI've never run into this issue in the wild. It sounds like a hypothetical. Upgrading your Rust toolchain is ridiculously easy, and using a year old outdated toolchain is more or less a philosophical hang up than a technical one.
- superkuh 9mo agoIt's not a hypothetical. I was put off the entire language after it happened to me three times in a row with unrelated Rust written software. This was 1 month after Debian 12 was released (June 10, 2023) and I was running the brand new Debian 12 with rustc 1.63.0 from August 11, 2022. I ran into it with some web serial spidering and epub creation rust software (rust-wildbow-scraper). I ran into with a software defined radio spectrogram visualizer (plotsweep); I actually knew the author from IRC and he was able to edit it to not use bleeding edge rustc features and I managed to compile it. I can't recall the third. In the years since when I've stepped my toes into the "compile random rust programs with repo rust toolchain" and it's been the same. But as you can see from my specific examples and dates: this is not a hypothetical. rust developer culture basically only writes for latest, having a 1 year old rustc is definitely not enough, and yes, installing compilers from a random website (curl site|sh) instead of my distro's repos is a problem. Just because it hasn't happened to you doesn't mean it isn't a problem. Rust is a rolling release only compiler.
- sfink 9mo agoHuh. 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?
- steveklabnik 9mo agoBoth of those things are important, sure. I wanted this post to be talking about the higher level conceptual question, and then using interesting examples to tease out various aspects of that discussion, more than "here's what I think are the biggest differences between the two." I think these two things are also things people would argue about a lot. It's hard to talk about them in a concrete sense of things, rather than just "I feel like code usually does X".
- sfink 9mo agoRight, sorry, I didn't mean to imply that you should have covered stack allocation in your post. I think your post covers the right material to make its point. This is more of a side comment about a different question, perhaps "ok fine, but then what are the language differences that could be performance-relevant for one language or the other, even if (as you say) they don't lead to a yes/no answer for your original question?"
- steveklabnik 9mo agoThe ones I think, personally: 1. crates.io makes it easy to use complex data structures. Basically this argument https://bcantrill.dtrace.org/2018/09/28/the-relative-performance-of-c-and-rust/ https://bcantrill.dtrace.org/2018/09/28/the-relative-perform... 2. Rust's safety guarantees making it easier to maintain more dangerous things over time. 3. On the C side, there's a lot more cultural understanding overall of how to use the language to get good performance results 4. It might be easier to find people who are experienced in heavily optimizing C code as opposed to Rust code.
- vitaut 9mo agoIt'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/91f07497a3f6e2fb3a9f999a7015a757b897503a/zmij.cc#L314-L327 https://github.com/vitaut/zmij/blob/91f07497a3f6e2fb3a9f999a... (likely impossible without an external pass to generate multiple lookup tables).
- vitaut 9mo agoOther examples are CTRE (https://github.com/hanickadot/compile-time-regular-expressions https://github.com/hanickadot/compile-time-regular-expressio...) and format string compilation (https://fmt.dev/12.0/api/#compile-api https://fmt.dev/12.0/api/#compile-api). The closest C counterpart is re2c which also requires external tooling.
- kazinator 9mo agoAssembly 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.
- stevefan1999 9mo agoYes, in general Rust is faster than C, I would argue, because there are some problems the hinders C performance such as strict aliasing and volatile data simply doesn't exist in Rust, and immutable const propagation and const evaluation works too.
- kevincox 9mo agoYes, the same way is that Fortran is faster than C due to stricter aliasing rules. But in practice C, Rust and Fortran are not really distinguishable on their own in larger projects. In larger projects things like data structures and libraries are going to dominate over slightly different compiler optimizations. This is usually Rust's `std` vs `libc` type stuff or whatever foundational libraries you pull in. For most practical Rust, C, C++, Fortran and Zig have about the same performance. Then there is a notable jump to things like Go, C# and Java.
- dwattttt 9mo ago> In larger projects things like data structures and libraries are going to dominate over slightly different compiler optimizations. At this level of abstraction you'll probably see on average an effect based on how easy it is to access/use better data structures and algorithms. Both the ease of access to those (whether the language supports generics, how easy it is to use libraries/dependencies), and whether the population of algorithms and data structures available are up to date, or decades old, would have an impact.
- esjeon 9mo agoTheoretically, C is likely faster than Rust only by an unnoticeably small margin. Still, this is unavoidable because Rust works with abstraction that (1) adds overhead per-se albeit tiny (2) forces overhead in the design level. Practically, that little margin can be removed thru a series of engineering, as both are proper system-level programming languages, which offer tight control over the generated machine code. That is, this whole discussion is basically pointless if we mix in engineering factors. We better talk about overall engineering costs, and personally I think Rust would not overshoot C easily, mainly due to the limitations that Rust puts on the higher level designs.
- steveklabnik 9mo agoWhat abstraction do you refer to?
- esjeon 9mo agoRust is actually few steps above from the bare metal, to enforce its security invariants. Boundary checks (which breaks auto-vectorization of loops), stack probe, fat pointer (wastes register), fixed index type (uint), etc. There are other hidden costs coming from usage of std. Even `Result` is a bit of inefficiency. I'm not saying any of these are bad. I'm just saying Rust would be slower than C if *naively* used.
- steveklabnik 9mo agoOkay, cool, I can see where you're going with this. I wouldn't exactly agree, because all of these things are stuff you can easily opt out of, but I thought you were maybe suggesting something like "the borrow checker has overhead" which I would take more direct issue with. (and yeah, the opt out question gets right to what you're saying about "naively used", I saw "unavoidable" but you're not actually saying it's unavoidable.)
- notorandit 9mo agoIt is machine code in the end, right? We all have optimizing compilers in 21st century, right? So, "yes, compilers can have different speeds. No matter the language." And "no, C and rust are both fast" unless compiler limitations kick in.
- shevy-java 9mo ago> An example of this from a long time ago is the Stylo project. 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. The third time, they used Rust, and managed to ship I am getting tired of those Rust-promo comments citing Firefox or other projects from Mozilla that also fail. Mozilla has consistently lost market share with Firefox. Nowadays it pushes things into it that the users do not want, so the death-cycle continues here; the whole AI slop is a wonderful example of this. I even had those things hover out (!) of firefox into other parts of my IceWM desktop. Even if this may be a separate bug or related to nouveau, why are those things I don't need, hovering outside of Firefox to begin with? I never asked or wanted for those things; Mozilla dictated that onto me. Yet there are people such as Steve, who constantly promote Rust - and cite Firefox or Mozilla. Something does not work here; the promo should instead be "thanks to Rust, Firefox is now chasing Chrome realistically again". But this is not happening. So why the promo? You can not promote a new language by pointing at failing projects. That makes no sense.
- steveklabnik 9mo agoI use chrome btw. It gets brought up because the conversation is not “is Firefox better than Chrome,” the conversation is about Rust’s multithreading guarantees. It’s just an entirely different conversation. For example, your own beefs with Mozilla have nothing to do with the technical choices made by the code.
- DarkNova6 9mo ago> But we’re not usually talking about that. We’re usually talking about something in the context of engineering, a specific project, with specific developers, with specific time constraints, and so on. I think that there are so many variables that it is difficult to draw generalized conclusions. The world would be a more reasonable place if more people took this by heart.
- seanw444 9mo agoI think the "social factors" section is the most significant. I've heard plenty of anecdotes of people stating that they "code defensively" in C, because it's too easy to mess things up. Whereas with a language such as Rust, you're able to be more aggressive in your optimizations without feeling like you're walking through a minefield unassisted. The end result is that the language with more constraints lets you be more safely free in your implementation.
- morshu9001 9mo agoSocial factors mentioned there can make a big difference. I've seen plenty of C code choose safety over efficiency. Our team writes a lot of C++ code for high-level stuff you'd normally do in say JS or Python. At the rate we make changes, we can't write very tight code. Strings and other structs end up getting copied needlessly due to ownership, like if something takes vector<string>& and internally copies those strings into a map, we don't bother also making an external-owned version taking vector<string*>&. Or less efficient algorithms are used due to ease of safe implementation. Or there are fewer or less optimized libs available. Or it's a webserver and we have to throw threads at it instead of event loops. The end result is C++ code that's slower than the equivalent Python code, dev time being equal.