Live data from Hacker News

Is Rust faster than C?

steveklabnik.com

321–330 of 402 posts

Re: Is Rust faster than C?

#321

Earlier quoted context omitted.

To be honest, I think a lot of the justification here is just a difference in standard library and ease of use. I wouldn't consider there to be any notable effort in making thread build on target platforms in C relative to normal effort levels in C, but it's objectively more work than `std::thread::spawn(move || { ... });`. Despite benefits, I don't actually think the memory safety really plays a role in the usage ra…

> To be honest, I think a lot of the justification here is just a difference in standard library and ease of use. I really liked this article by Bryan Cantrill from 2018: https://bcantrill.dtrace.org/2018/09/28/the-relative-perform... He straight ported some C code to rust and found the rust code outperformed it by ~30% or something. The culprit ended up being that in C, he was using a hash table library he's been co…

> He straight ported some C code to rust and found the rust code outperformed it by ~30% or something. The culprit ended up being that in C, he was using a hash table library he's been copy pasting between projects for years. In rust, he used BTreeMap from the standard library, which turns out to be much better optimized.

Are you surprised? Rust is never inherently faster than C. When it appears faster, it boils down to library quality and algorithm choice, not the language.

Also worth noting that hash tables and B-trees have fundamentally different performance characteristics. If BTreeMap won, it is either the hash table implementation, or access patterns that favor B-tree cache locality. Neither says anything about Rust vs C. It is a library benchmark, not a language one.

Re: Is Rust faster than C?

#322
post #122

Earlier quoted context omitted.

what about generics (equivalent to templates in C++), which allow compile time optimizations all the way down which may not possible if the implementation is hidden behind a void*?

Unless you use `dyn`, all code is monomorphized, and that code on its own will get optimized. This does come with code-bloat. So the Rust std sometimes exposes a generic function (which gets monomorphized), but internally passes it off to a non-generic function. This to avoid that the underlying code gets monomorphized. https://github.com/rust-lang/rust/blob/8c52f735abd1af9a73941...

There is also the "momo" crate to do the same with a procedural macro attribute (https://docs.rs/momo/latest/momo/).

Re: Is Rust faster than C?

#323
post #171

Earlier quoted context omitted.

And the C++ version is add std::execution::par_unseq as parameter to the ranges algorithm.

This has the same drawbacks as "#pragma omp for". The hard part isn't splitting loop iterations between threads, but doing so _safely_. Proving an arbitrary loop's iterations are split in a memory safe way is an NP hard problem in C and C++, but the default behavior in Rust.

Concurrency is easy by default. The hard part is when you are trying to be clever.

You write concurrent code in Rust pretty much in the same way as you would write it in OpenMP, but with some extra syntax. Rust catches some mistakes automatically, but it also forces you to do some extra work. For example, you often have to wrap shared data in Arc when you convert single-threaded code to use multiple threads. And some common patterns are not easily available due to the limited ownership model. For example, you can't get mutable references to items in a shared container by thread id or loop iteration.

Re: Is Rust faster than C?

#324
post #76

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…

    > When writing single-threaded code takes 90% of effort of writing multi-threaded one
That "when" is doing some heavy lifting! More seriously: You raise a very interesting point. When I moved from C++ to Java (10+ years ago), I was initially so nervous to add threads to my Java code. Why? Because it was (then) difficult and dangerous to do it in C++. C++ debuggers were awful, so I didn't think I could debug problems with multi-threaded C++ code. (Of course, the C++ ecosystem has drastically improved in the last 10 years, so I am sure it is now much more pleasant (and safe) to write multi-threaded C++ code.) When I finally sat down to add threads to some Java code, I could not believe how easy it was, including debugging. As a result, going forward, I was much more likely to add threads to my Java... or even start with a multi-threaded design, even if there is only a modest performance improvement.

Re: Is Rust faster than C?

#325
post #308

Earlier quoted context omitted.

> Multithreaded by default seems like it would be an insane choice without all the safety machinery You're describing golang, and somehow it's fine. Bugs are possible, but not super common

Isn't that "somehow" super attributable to the fact that Go is garbage collected? Garbage collection is the one other known way to achieve memory safety.

You raise a good point here. When I think about writing multi-threaded code, three things come to mind about why it is so easy in Java and C#: (1) The standard library has lots of support for concurrency. (2) Garbage collection. (3) Debuggers have excellent support for multi-threaded code.

Re: Is Rust faster than C?

#326

Earlier quoted context omitted.

> To be honest, I think a lot of the justification here is just a difference in standard library and ease of use. I really liked this article by Bryan Cantrill from 2018: https://bcantrill.dtrace.org/2018/09/28/the-relative-perform... He straight ported some C code to rust and found the rust code outperformed it by ~30% or something. The culprit ended up being that in C, he was using a hash table library he's been co…

> He straight ported some C code to rust and found the rust code outperformed it by ~30% or something. The culprit ended up being that in C, he was using a hash table library he's been copy pasting between projects for years. In rust, he used BTreeMap from the standard library, which turns out to be much better optimized. Are you surprised? Rust is never inherently faster than C. When it appears faster, it boils down…

> library quality and algorithm choice

And especially having performant and actively maintained default choices built in. With C, as described in the post you responded to, you'll typically end up building a personal collection of dusty old libraries that work well enough for most of the time.

Re: Is Rust faster than C?

#327
post #80
post #75

Earlier quoted context omitted.

> On the other hand, signed integer overflow being UB would count for C/C++ C and C++ don't actually have an advantage here because this is only limited to signed integers unless you use compiler-specific intrinsics. Rust's standard library allows you to make overflow on any specific arithmetic operation UB on both signed and unsigned integers.

It's interesting, because it's a "cultural" thing like the author discusses, it's a very good point. Sure, you can do unsafe integer arithmetic in Rust. And you can do safe integer arithmetic with overflow in C/C++. But in both cases, do you? Probably you don't in either case. "Culturally", C/C++ has opted for "unsafe-but-high-perf" everywhere, and Rust has "safe-but-slightly-lower-perf" everywhere, and you have to g…

The rust standard library does make targeted use of unchecked arithmetic when the containing type can ensure that that overflow never happens and benchmarks have shown that it benefits performance. E.g. in various iterator implementations. Which means the unsafe code has to be written and encapsulated once, users can now use safe for loops and still get that performance benefit.

Re: Is Rust faster than C?

#328
post #326

Earlier quoted context omitted.

> He straight ported some C code to rust and found the rust code outperformed it by ~30% or something. The culprit ended up being that in C, he was using a hash table library he's been copy pasting between projects for years. In rust, he used BTreeMap from the standard library, which turns out to be much better optimized. Are you surprised? Rust is never inherently faster than C. When it appears faster, it boils down…

> library quality and algorithm choice And especially having performant and actively maintained default choices built in. With C, as described in the post you responded to, you'll typically end up building a personal collection of dusty old libraries that work well enough for most of the time.

I think Rust projects will accumulate their own cruft over time, they are just younger. And the Rust ecosystem's churn (constant breakage, edition migrations, dependency hell in Cargo.lock) creates its own class of problems.

Either way, I would like to reiterate that the comparison is flawed at a more fundamental level because hash tables and B-trees are different data structures with different performance characteristics. O(1) average lookup vs O(log n) with cache-friendly ordered traversal. These are not interchangeable.

If BTreeMap outperformed his hash table, that is either because the hash table implementation was poor, or because the access patterns favored B-tree cache locality. Neither tells you anything about Rust vs C. It is a data structure benchmark.

More importantly, choosing between a hash table and a tree is an architectural decision with real trade-offs. It is not something that should be left to "whatever the standard library defaults to". If you are picking data structures without understanding why, that is on you, not on C's lack of a blessed standard library (BTW one size cannot fit all).

Re: Is Rust faster than C?

#329

Earlier quoted context omitted.

Apart from multi threading, there is more information in the Rust type system. Would that would allow more optimizations?

In C there is the "restrict" keyword to tell the compiler that there is no other pointer to the values accessed over a certain pointer. If you do not use that the generated code can be quite suboptimal in certain cases.

    > If you do not use that the generated code can be quite suboptimal in certain cases.
I believe you, but I don't understand it. Can you give a simple example to demonstrate your point?

Re: Is Rust faster than C?

#330
post #51

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 int…

This is a tangent, because it clearly didn’t pan out, but I had hope for rust having an edge when I learned about how all objects are known to be immutable or not. This means all the mutable objects can be held together, as well as the immutable, and we’d have more efficient use of the cache: memory writes to mutable objects share the cache with other mutable objects, not immutable Objects, and the bandwidth isn’t wa…

I think it would be quite difficult to actually arrange the memory layout to take advantage of this in a useful way. Mutable/immutable is very context-dependent in rust.
Post reply on HN