Is Rust Faster Than C?

Is Rust Faster Than C?

Recently, someone on Reddit asked:

Under the same conditions, what method would allow Rust to achieve better performance than C?

I think this is a great and interesting question! It is actually quite difficult to answer because it ultimately depends on the specific meaning of “the same conditions”.

I believe this also makes comparisons between languages challenging. There are several ways to argue about what is “the same” and “different” and how they affect runtime performance.

Inline Assembly

The Rust language has built-in support for inline assembly. In contrast, C treats inline assembly as a very common compiler extension, to the point where saying it is not part of the language is a controversial nitpick.

Let’s look at a code example in Rust:

The following is a function rdtsc that reads a timestamp and returns its value. Here is an example implementation in C:

#include <stdint.h>

uint64_t rdtsc(void)
{
    uint32_t lo, hi;
    __asm__ __volatile__ (
        "rdtsc"
        : "=a"(lo), "=d"(hi)
    );
    return ((uint64_t)hi << 32) | lo;
}

Here is a program with the same functionality under rustc 1.87.0 and clang 20.1.0:

rdtsc:
        rdtsc
        shl     rdx, 32
        mov     eax, eax
        or      rax, rdx
        ret

Here is the link to the online compiler site Godbolt:

https://godbolt.org/z/f7K8cfnx7

Does this count? I don’t know. I feel it doesn’t relate much to the question itself, but at least it’s a way to answer the question.

Similar Code, Different Results

Rust and C can have different semantics for similar code. Here is a struct in Rust:

struct Rust {
    x: u32,
    y: u64,
    z: u32,
}

This is the “same” struct in C:

struct C {
    uint32_t x;
    uint64_t y;
    uint32_t z;
};

In Rust, this struct is 16 bytes (also on x86_64), while in C, it is 24 bytes. This is because Rust can freely reorder fields to optimize size, while C cannot.

Social Factors

Some people report that due to Rust’s safety checks, they are more willing to write code that is “riskier” than equivalent C (or C++) code, because in C (or C++), they would do more copying to ensure the code is safer. From the perspective of the same developers in the same project, this seems “the same”, but due to judgment calls, the code will differ.

A long time ago, there was an example with the Stylo project. Mozilla attempted twice to parallelize the Firefox browser’s style layout with C++, but both times failed because multithreading was too tricky to implement. The third time, they used Rust and successfully delivered.

This is the same project (though I don’t think it was the same programmer), developed by the same organization, but one was feasible while the other was not.

Similar questions apply: suppose we have a junior developer who writes both Rust and C to accomplish the same task. Can we write faster code in one of the languages? This question depends on their skill level, but it has nothing to do with writing the same code. Is this “the same”? I don’t know. What if the same task is given to experts in both languages, one very proficient in Rust but not familiar with C, and vice versa? What is the difference from a junior developer or an “average” developer?

Compile Time vs Runtime?

Another Reddit user asked at the bottom of the question:

I am not a Rust expert, but aren’t most (all?) safety checks compile-time checks? They shouldn’t affect runtime.

This is also a good question! This part is another example of different defaults.

<span><span>For example, the declaration of <code>array[0] is valid in both languages.

Rust performs boundary checks at runtime. C does not have this capability. In Rust, I can write array.get_unchecked(0) and get C’s semantics. In C, I need to write boundary checks to achieve Rust’s semantics.

In Rust, if the compiler can prove it is safe, then that check may be optimized away. In C, if we write boundary checks by hand, and the compiler can prove it is safe, then that check may also be optimized away.

Many of Rust’s safety checks are done at compile time, but some work is done at runtime. But this raises another interesting question: compile-time checks may lead you to write code differently than in C for the same task.

A common example is using indices instead of pointers, which means the generated code behaves differently. Are these checks really done “at compile time”? Technically, at a micro level, yes. But at an engineering level, it may not be so!

Conclusion

I think the most important part of this question relates to the so-called possibilities, namely:

  1. If we assume C is “the fastest language”, whatever that means;
  2. Is there an internal reason why Rust cannot do the same things?

I believe the answer is “no”, even ignoring the case of inline assembly. So at this most important, fundamental level, the answer is “there is no difference between the two”.

But we usually do not talk about these. We typically discuss something in the context of engineering, such as a specific project, with specific developers, under specific time constraints, etc. I think there are too many variables here to draw a general conclusion.

Author: Steve Klabnik

Translation: Luo Yi

Original:

https://steveklabnik.com/writing/is-rust-faster-than-c

Related Reading:

OpenAI Rewrites AI Programming Tools in Rust

Code Wars: Rust vs C Competing for Security on a Billion Devices!

Cursor AI Editor Reaches 1.0 Milestone

Leave a Comment