Live data from Hacker News

Why is Rust slightly slower than C?

github.com

61–70 of 251 posts

Re: Why is Rust slightly slower than C?

#62
post #44

The two biggest factors involved are (1) Runtime. Even though C has "no" runtime, there is some runtime overhead: Variable allocation / de-allocation and alignment. Function invocation / call stack setup. Et cetera. I don't know enough about Rust to understand what its exact "runtime" is like, but I'd bet it's not exactly like C. (Rust is strongly-typed, is it not? Does it do run-time type-checking?) Exception handli…

Others have pointed out that Rust's type-checking is all done at compile time. Rust also does not have exception handling. To be more specific: errors in Rust are either propagated by function return values (usually in the form of `Result` or `Option` types) which do not require any kind of runtime support, or by panicking, which unwinds the stack for clearing-up of resources and then halts the running thread. (Panic…

The thread boundary restriction for catching panics was lifted quite a while ago with std::panic::catch_unwind: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html

Do note the caveats in the docs though. It isn't guaranteed to catch all panics. Indeed, unwinding can be disabled completely with a compiler option (instead, panics will abort).

Re: Why is Rust slightly slower than C?

#63
post #58
post #42

Earlier quoted context omitted.

Yeah, their initial explanation is that its the "safety features", but I was under the impression that literally everything related to rust's safety happens at compile time. Their big selling point is the "zero cost abstractions".

Their initial explanation is bounds checking specifically. While most abstractions are zero-cost, bounds checking isn't. I do wish there were a way to track expectations about integer ranges in a type system, but there currently aren't.

Might I intrest you in dependent types? Sadly we don't even have a self hosted compiler yet.

Re: Why is Rust slightly slower than C?

#64
post #45
post #42

Earlier quoted context omitted.

Yeah, their initial explanation is that its the "safety features", but I was under the impression that literally everything related to rust's safety happens at compile time. Their big selling point is the "zero cost abstractions".

While you are spot on with zero cost abstractions a bounds check in Rust is not without penalty (if enabled, should be off in release mode)

Bounds checks are always on. Integer overflow checks are disabled in release mode. Bounds checks are necessary for memory safety, whereas integer overflow isn't

Re: Why is Rust slightly slower than C?

#65
post #45
post #42

Earlier quoted context omitted.

Yeah, their initial explanation is that its the "safety features", but I was under the impression that literally everything related to rust's safety happens at compile time. Their big selling point is the "zero cost abstractions".

While you are spot on with zero cost abstractions a bounds check in Rust is not without penalty (if enabled, should be off in release mode)

I believe release mode keeps bound checks. It's integer overflow checks it gets rid of.

Re: Why is Rust slightly slower than C?

#66
post #20

Looking at performance counter data is good, but I would have liked to see a real validation of the hypothesis that bounds checking is to blame for the extra branches and instructions. That is, modify the Rust compiler to not emit bounds checks (or maybe there is even a flag for this?) and look at performance and counters. I would imagine that this would bring the data for Rust to pretty much the same as C. But other…

In case anyone is interested, rust has unsafe methods to index arrays without bounds checking: https://doc.rust-lang.org/std/primitive.slice.html#method.ge...

Sounds much worse than the compile time flag.

Re: Why is Rust slightly slower than C?

#67
post #54

Earlier quoted context omitted.

I’m not 100% sure if there’s a source exactly, but we don’t like safety and correctness to depend on what flags you pass or do not pass. We don’t offer a fast-math flag either for similar reasons. The odd one out is overflow, and that’s only because it’s well defined (a “program error”) and not UB to overflow in Rust. This gets checked in debug but not currently release, though the spec allows for it.

I guess my thought is that much of correctness comes from the compiler being able to make assertions that some type (and thus some memory address) will only be used in a correct way at compile time, etc, etc. For example if we were dynamically linking a Rust crate into a Rust binary is it necessary to check boundaries in both or can some of that be deferred because we can assume the binary that will link has already…

There are unbound-checked versions of that call. You can make that simplifying assumption in your code if you'd like.

Re: Why is Rust slightly slower than C?

#68
post #37

On how "fast" C is, guys, sorry to say this, but in my experience actually (1) even assembler is not very "fast", (2) for much the same reasons C is not very fast, (3) often Fortran is faster than C, and (4) PL/I can be the fastest of all of (1)-(4). More generally, how Fortran and PL/I can be faster than C should be exploited quite generally but apparently has not been fully generally. Why? How can Fortran and PL/I…

How current is this impression? There continue to be first-rate Fortran compilers that probably win on numerics for exactly the reasons you state, but I would be surprised that PL/I has a toolchain that's kept up with modern architecture. String handling, on most modern toolchains, mostly goes to inline functions or builtins that the compiler has been (rather pragmatically, if a big disgustingly) made aware of. It's…

My experience is old, but my summary point remains: Language defined and compiler supported functionality usually is faster than libraries of external functions.

The relevance here: C isn't the fastest thing around and can be beaten. Maybe similarly for Rust.

For PL/I and strings, for the IBM versions on S/360 and S/370, the compiler might have used some of the hardware instructions for string handling.

I'd be surprised if in C strcpy, etc., were not still external: They USED to be, and then someone might have written their own version, e.g., for their own versions of strings, and linked to it; for compatibility, strcpy would about have to be an external function call still.

Re: Why is Rust slightly slower than C?

#70
post #20

Earlier quoted context omitted.

In case anyone is interested, rust has unsafe methods to index arrays without bounds checking: https://doc.rust-lang.org/std/primitive.slice.html#method.ge...

Sounds much worse than the compile time flag.

Not really: indexing out of bounds without this check would invoke undefined behaviour. A compile time flag would not be able to distinguish the cases where a bounds check is required for the program to be correct, from the cases where the index is provably within bounds and so is unnecessary.

Who wants a compile-time flag that makes valid programs have undefined behaviour? Nobody, especially when you consider that UB in any language really does mean undefined: in the best case the program crashes, in the worst it deletes all your files.

What's wanted is a way to tell the compiler "no, in this specific case which I have determined to be a bottleneck in my program, I want to omit bounds checking because due to XYZ it's impossible for the index to ever be out of bounds" and that's exactly what this method provides.

Post reply on HN