Performance of Rust Language [pdf]
github.com
Performance of Rust Language [pdf]
1–10 of 146 posts
Re: Performance of Rust Language [pdf]
#2Re: Performance of Rust Language [pdf]
#3If I followed, Rust's memory safety guarantee means sacrificing roughly ~3% performance with some worst case paths being ~15% (compared to C++ performance)?
But no, "memory safety" includes most of the things discussed on the slides, and those number are for bounds checking only.
Re: Performance of Rust Language [pdf]
#4Compounding on this, Rust is also unstable underneath, since there is no public, stable contract for carrying high-level semantics from HIR into MIR. Because these high-level invariants are lost during compilation, the compiler cannot easily use them to prove and eliminate low-level safety checks. But even if the frontend was perfect, Rust relies on LLVM's language-neutral SCEV, which operates purely on low-level math and cannot reason about high-level language semantics.
Ultimately, a lot of things would need to change for Rust to pay no performance for safety features.
Re: Performance of Rust Language [pdf]
#5 let mut tab: [usize;100] = [0;100];
...
for i in 0..101 {
tab[i] = i;
}
This must panic at i=100. Panic becomes inevitable at entry to the loop.
Is the compiler entitled to generate a check that will panic at loop entry?
The slides suggest that Rust does not hoist such checks, and, so, with nested
loops, it has trouble getting checks out of the loop, which prevents vectorization.Re: Performance of Rust Language [pdf]
#6There's a discussion of "delayed bounds checking", but not "hoisted bounds checking", where bounds checking is done early. Consider let mut tab: [usize;100] = [0;100]; ... for i in 0..101 { tab[i] = i; } This must panic at i=100. Panic becomes inevitable at entry to the loop. Is the compiler entitled to generate a check that will panic at loop entry? The slides suggest that Rust does not hoist such checks, and, so, w…
Even if the panic message would not include the index, LLVM was unable to do that if the previous iterations had side effects (for example if `tab` is not a local variable).
Re: Performance of Rust Language [pdf]
#7I think most of this is attributable to the ergonomics of compile-time expressiveness. C++ can effortlessly do things that require mountains of ugly boilerplate and macros in C or Rust. In principle they can express the same things but no one wants to write or deal with that ugly boilerplate so the equivalency is never realized in real code bases.
Zig is interesting because it slots in as a C-like language with a competent and expressive compile-time story. I don’t use Zig but I recognize its game.
Re: Performance of Rust Language [pdf]
#8Rust is in an awkward position of being already complicated enough that adding proofs for skipping bounds checks probably will not happen for a long time, even though this kind of low-level operation is where a lot of optimisation is lost. Compounding on this, Rust is also unstable underneath, since there is no public, stable contract for carrying high-level semantics from HIR into MIR. Because these high-level invar…
There are techniques to minimize the perf loss, though (safely), and of course you can use unsafe code. If you do it smartly, in the vast majority of cases bound checks do not matter (in fact, even in C++ there is a push for a hardened standard library that does bound checks, and e.g. Google uses that).
Rust will never include full proofs, but it might include ranged integers which can minimize bound checks even more.
Re: Performance of Rust Language [pdf]
#9Re: Performance of Rust Language [pdf]
#10I would summarize it thusly: Rust is roughly as performant as C. This matches my experience and Rust is more ergonomic than C in many regards. The caveat is that modern C++ is notably more performant than C and by implication Rust. This also matches my experience for both C and Rust. I think most of this is attributable to the ergonomics of compile-time expressiveness. C++ can effortlessly do things that require moun…
If anything, Rust has the potential to be more performant than C due to its aliasing rules (C has `restrict` but it's rarely used, standard C++ does not have even that). The current perf stats show it does make Rust code faster but just a little bit, although we don't utilize the full optimization potential currently (LLVM does not do many possible optimizations here, and `noalias` is weaker than Rust's aliasing rules). It can also affect autovectorization, and if it does the effect could be dramatic.