Is there a compelling argument against the statement that Rust is slower than C/C++ in some areas?

this is perhaps the single reason why I am not completely convinced to make Rust my main language. (I want to develop performance critical software systems but not OS drivers). Do you have objections against this?
What about the argument: in any performance critical section you can just use unsafe rust and test it well to match performance.

In both languages you may trivially achieve perfection by just adding asm (or asm!, in Rust), adding machine code and thus betting the best possible result.

For discussion to have some merit we need to put some constraints on the code that we are considering β€œsane”.

14 Likes

Be sure to read at least several articles on the topic, from different sources, to get a balanced viewpoint. In my reading, among C/C++/Rust/Zig one is sometimes faster, sometimes slower, depending on the benchmark, the test system, etc.

I would also not rely solely on posts made here that make claims about one being faster than the other. If you want an objective answer, don't ask the Rust community (or the C/C++/Zig community) this question.

20 Likes

In practice there's a million reasons why one example might be slower than another, but there's no reason in theory that Rust should be slower, given that clang uses the same backend and AFAIK nobody considers that slower in general than GCC.

The most likely reasons that some example might be slower in rust than another in C++ are:

  • You forgot to use --release :face_savoring_food:
  • It's comparing newer, less heavily tuned code. Nothing to do with Rust, just which order the code was written.
  • Natural / idiomatic Rust code simply does more than the equivalent-looking C++: bounds checking is the most obvious example, but another case is happy-path enforced Result-unwrapping is a bit more expensive than the equivalent C error codes or C++ exceptions... in theory. This is a trade-off for correctness, but only when the optimizer can't get rid of it, and you can always get the equivalent C behavior and performance with only a bit of ugliness (unsafe { a.get_unchecked(i) } instead of a[i] for example)
  • There's a missed optimization for some reason or another: similarly to the second case above, but for the Rust compiler itself. Generally not terribly common in practice on average since LLVM is doing most of the heavy lifting, but if you're looking at single percent performance changes you'll flush a bunch of these out. This is where you might need to drop down to asm! earlier than in C.

In exchange, you get a codebase that can potentially be much more reliably heavily refactored, which can lead to performance wins over long standing C code; IIRC recently the Rust DEFLATE implementation leapfrogged the original, ancient, heavily tuned C zlib by being able to do something like two complete rewrites without fear of introducing security holes.

There's also the much more strict aliasing rules in Rust that in theory should allow more aggressive optimizations, but I haven't actually seen numbers on that yet.

In summary; everything is a trade-off. FORTRAN still beats C in some cases!

33 Likes

IIRC someone very recently submitted optimizations to the ffmpeg project in the form of a bunch of assembler patches that turned out to originally be Rust code that was compiled to simd assembly.

Then there are things like this to consider:

Idiomatic Rust code should be faster than idiomatic C++ code. [---] Of course, we all know that theory and practice are not always the same thing. At present I don't think that Rust performance promise is fully realized in practice.

That is to say; if you're looking for a "main (long term) language", then you should probably take these things into account; it's not just what the language can do today, but what it can do once its full potential has been realized.

That entire talk is very interesting, btw -- and there are other talks about codegen and memory safe languages on the LLVM YouTube channel that are well worth listening to.

Anecdotally, we have a highly performance-critical transmission system that was first written in C, then C++ and now is rewritten in Rust. We couldn't use threads in the C or the C++ versions, but with Rust we can, and one could say it's currently in a completely separate category of performance thanks to the parallelization. Before we had to have meetings before making any changes to the core transmission system to make sure no one stepped on anyone else's toes, but now we have so many CPU cycles to spare that we very rarely have to coordinate changes.

17 Likes

I think this is the best performance argument in favor of Rust. You can introduce optimizations like multi-threading, or passing around references to data rather than copies, with fewer correctness hazards. You're not doing anything you couldn't do in C/C++, but it is more manageable as the codebase and team scales.

22 Likes

Comparing newly written code with heavily fine tuned code, daring, aren't we? :sweat_smile:

Sorry for the aggressive tone, but it's really annoying to see (official?) accounts throwing out bad arguments (with a bad tone as well!) like this.

4 Likes

First of FFMpeg is definitely on some kind of anti-Rust crusade. Not sure why. He's writing mostly assembly anyway.

I think dav1d is an extreme example.

  • Code is continuously transpiled from C to Rust, then edited by hand.
  • Difference isn't huge 5%
  • Extra bounds check account for 1% of performance hit.

So what did the performance search find:

  • small performance boost using uninitialized values.
  • #[derive(PartialEq)] doesn't optimize well on LLVM or Rust.
  • obscure u16 comparison bugs in LLVM, that dav1d works around.
6 Likes

ffmpeg in particular has had many CVEs. Here's just one: https://www.cve.org/CVERecord?id=CVE-2025-1594.

9 Likes

If that's true, there's a good chance rav1d has the same vulnerability as well. It's mostly transpiled dav1d + some tweaks.

rustc and clang both compile through LLVM. It's the optimizations in LLVM that make both fast, not anything about the input language, as both have sufficient low-level operations. There's no consistent speed difference between them at the language level; choices in how the program is written affect things far more.

Look at the box plots on Charts showing the fastest programs by language (Benchmarks Game) -- C, C++, and Rust are all about as fast as each other. (The benchmarks game has its problems, in that most of the programs are horribly non-idiomatic so the results are meaningless for how people normally write code in the language, but these box plots are a reasonable answer for the also-mostly-meaningless question of which languages are "faster".)

11 Likes

I've written a detailed comparison if you're interested.

In short:

  • There's no upper performance limit if you allow use of unsafe. It's essentially identical to C++ in terms of capabilities. You don't always need unsafe, and when you do, you can usually contain it behind a safe API, so most of your code benefits from staying safe and using a modern language.

  • In some cases Rust can be faster than C and C++ thanks to stronger immutability and no-alias guarantees that let LLVM optimize code more aggressively. For example, the Rust png crate beats libpng, and recently even removed the last hand-written SIMD code, because plain safe Rust code turned out to be as fast. Rust png copied some filtering functions from stb_image, and the same code gets autovectorized in Rust, but not in C++.

  • Some small technicalities, coding style, and compiler differences can give you +/- a few % of performance in either direction, but this is insignificant compared to 1000%+ speedups you can get from going from single-threaded to multi-threaded code on modern CPUs. C++ technically can do it, but the risks of hard-to-debug bugs usually make C++ programmers avoid multi-threading, or apply only minimal coarse-grained parallelism. Rust can do it easily, so multi-threading is the norm.

16 Likes

Note that Rust supports AVR too (not just MSP430), which also acts like a 16-bit architecture even though it's an 8-bit architecture since it has 16-bit pointers in Rust. So, I think "It's worth noting that Rust currently supports only one 16-bit architecture." is a bit misleading.

If the programs are horribly non-idiomatic so the results are meaningless for how people normally write code in the language β€” none of which you've demonstrated β€” then the same results would still be meaningless when shown in a box plot.

Seems like you want to have your cake and eat it too.

As people have said, Rust is slightly slower than C in some cases and slightly faster in others. Besides that, you can write inefficient algorithms in both languages, so it's possible that the Rust version just needs to use better algorithms.

But look, here's the point. No memory-safe language came close to matching the performance of C until Rust (to my knowledge, at least). It used to be that if you wanted to write high-performance systems software, you had to use an unsafe language, because safe languages had tracing garbage collectors and runtimes and were simply unsuitable for the task. This is no longer the case with Rust. Maybe the Rust video decoder is 5% slower than the C one, but that still puts it in the class of suitable implementations for the task IMO. You would not get that kind of performance with almost any other safe language.

So is using a safe language worth a potential 5% performance hit? To me, probably. First, as someone said, there is likely potential for further optimizations to close that gap. Second, when I'm writing new software, you can bet that I'd rather be writing the actual algorithms, adding features, etc. than spending hours tracking down mysterious segmentation faults and constantly worrying about my code having bugs.

5 Likes

Well they say themselves

We've certainly not attempted to prove that these measurements, of a few tiny programs, are somehow representative of the performance of any real-world applications β€” not known β€” and in-any-case Benchmarks are a crock.

If anything the normal results are much better for Rust. See things like The relative performance of C and Rust | The Observation Deck where things like the lack of generics and the corresponding difficulty in using libraries in C mean that the Rust version is materially faster than the C version.

But there's all kinds of numbers all over the place. Just make it scale: An Aurora DSQL story | All Things Distributed is a neat article with great results, but even with it giving a 10x to 15x improvement, I wouldn't personally use that to say that "Kotlin as a language is 10x slower than Rust".

Getting data is hard, when you need something more than a bunch of university students for Β½ an hour each.

If the OP wants to ask a more specific question, then they could get a more specific answer. With a vague question, imperfect data showing that "they're about the same" seems entirely fine as a response, especially in conjunction with white-box implementation reasons for that to be true.

8 Likes

Well they say themselves …

The sentence you quote speaks about representative performance not about idiomatic / non-idiomatic.

… imperfect data showing that …

The data was not said to be "imperfect".

The data was said to be "meaningless".

After which β€” Look at the boxplot! β€” is not "entirely fine as a response".

I can ignore %3 performance loss for memory safety, strong typing and feel comfortable. If you really want high performance than buy hardware. We aren't living at 60s, hardware improved a lot. Comparing loop benchmarks between low level languages is weird and nonsense. Just use rust, become idiomatic and professional, that's it.

Edit: I think unsafe rust is more safe than C/C++ :wink:

1 Like

Why do you think that?

When you write unsafe rust you must think twice because code came from safe and going to safe too.