Benchmarks would be interesting, in the sense that it would help make sure that the translation is doing the same thing, but it wouldn't say a ton about Rust vs C in a more general case. This translates to unsafe code, which means it's not really representative of Rust generally.
We didn’t benchmark this project (yet) but previous c2rust translations had approximately equal performance to the original. This is to be expected since the transpiled output is unsafe Rust that is equivalent to the original C code. One caveat is checked va unchecked array indexing, but unless an array indexing operation into a statically sized array is hot _and_ the Rust compiler can’t elide the checks, that’s unlikely to make much of a difference.
What is the realistic best-case scenario? Has anyone demonstrated that well-written Rust code should run faster than C, or is the hope simply to get performance parity with C while maintaining memory safety?
This topic is really tricky, and there's a lot of different ways to slice it. In the most general sense, if you take a C expert, and a Rust expert, and ask them to do something, they should be able to get the exact same results.
But that leaves out other interesting questions that inform this comparison. For example:
* What about the average Rust programmer vs the average C programmer? Maybe two experts can produce identical results, but does one language vs the other make it so that a non-expert tends to produce faster code?
* What about "no unsafe Rust other than what's in the implementation of the standard library"? Most Rust code doesn't use unsafe, so is it fair to let the Rust use it? How much?
* What about "no code other than the standard libraries." I may not be an expert, but Rust's package ecosystem makes it easier to use code that's developed by them. This is sort of a slightly different take on the two previous questions at the same time.
* Should there be a time limit on development? If so, should the C have the same requirements of demonstrating safety as the Rust, that is, sketching out an informal proof of correctness?
* What about some sort of "how maintainable is this" metric. Mozilla tried to implement parallel CSS in C++ twice, and couldn't do it, because the concurrency bugs were just too many. Their Rust attempt succeeded, thanks to the safety guidelines. Is this comparison valid? Or could some sort of person who was better at C++ have implemented it in theory with no bugs? (this is sort of question 1, but slightly different.)
Theoretically I would argue that Rust could get faster than C, because it can make stronger guarantees about the code that would allow further and much more complex optimizations of the code. You could argue that the set of possible outputs of a piece of C code is much wider than a piece of Rust code and you could compile the code down to some sort of state machine that equivalently represents the original code in a more compact form. The more well defined the outputs are, the more minimal the output representation could be.
I think it would be particularly interesting to compare idiomatic Rust and C code. For example, given C's lack of generics, I would expect Rust to have a number of wins, including better inlining opportunities for polymorphic functions a la qsort.
Yes, the most recent example I can think of is http://cliffle.com/p/dangerust/ in which the author translates heavily optimized C to Rust in a quite mechanical way. It comes out being slightly faster. In the last part they rewrite it in idomatic Rust and it ends up even faster again without any of the bespoke optimizations that the C code used or any unsafe Rust.
In many instances the Rust type system should allow the compiler to emit faster code because it has more data to use for reasoning about valid and invalid states of the program. Depending on how good c2rust is the Rust version should be roughly as fast, refactored to idomatic Rust it could be meaningfully faster than C.
Rust will outperform C consistently soon. It already does in some cases. It will also do so with safe idiomatic code in most cases. The reason behind my statement is simply more opportunity for the optimizer. Rusts rules allow for a more aggressive optimization. The reasons why it's not outperforming C yet are LLVM bugs and some missing Rust language features and fixes. LLVM in particular is driven by C needs so they rarely fix bugs present only Rustc generated IR.
This is grey, but shouldn’t be. I assume people are downing it because it doesn’t give examples of the optimization opportunities it claims. So here are two that I think are likely most significant.
1. Rust’s aliasing semantics are more powerful than C’s unless you use the ‘restrict’ keyword everywhere, which most people don’t. It’s well recognized that FORTRAN continues to generally outperform C in many numeric applications because FORTRAN compilers are free to perform optimizations that C compilers cannot or don’t, due to the fact that multi-aliasing memory is undefined behavior in FORTRAN. The rust compiler currently doesn’t pass the relevant hints to the generated LLVM IR due to a long history of LLVM having bugs in ‘noalias’ handling, in large part due to the fact that those code paths are so rarely executed while compiling C code, itself due to the relatively low usage of the ‘restrict’ keyword.
2. Implicit arena allocations. The Rust compiler has access to information about possible aliasing and overlapping lifetimes that it can use to replace multiple allocations with similar lifetimes with offsets into a single allocation that is then all freed together. This is a complicated topic, but work is ongoing to make this a reality.
2 might sound overly optimistic like "Rust will eventually beat C" but V8 already has an allocation folding optimization which combines multiple objects into a single site. There's also run time profiling to try and figure out the allocation lifetime.
I'm not disputing that. In theory Rust should outperform even today but of course reality is a different beast and implementation details are important.
Then you also get into architecture specifics etc.
dodobirdlord described the two major advantages Rust has on the language level very well so I won't repeat them, but the gist I'm making is that Rust simply allows more optimizations purely on the language level. Specifics of backend implementations are of course another topic completely (and is one of the reasons why I'm excited for the possibility of a GNU Rustc)
There are some "shoulds" related to aliasing I believe. Things the compiler can assume when compiling a rust program that it can't when compiling C, which should in theory let it generate more efficient code.
But last I heard Rust wasn't taking advantage of this due to issues with LLVM. The same benefits should also be achievable in C with pragmas.
> The same benefits should also be achievable in C with pragmas.
I don't know that any compiler provides a noalias-all pragma. I don't know that it would be very sane either since C very much defines pointers as aliasing by default. Plus you wouldn't have any way to revert this behaviour and mark pointers as aliasing.
> C very much defines pointers as aliasing by default.
This is actually a huge issue for the CRuby JIT which generates C from the VM bytecode. Alias analysis on the generated C code, which is full of indirection, is basically useless and severely restricts the possible optimizations.
Not answering directly your question, but I remember seeing a benchmark recently where there was more difference in performances for a program compiled with gcc and clang, than between the C++ clang and Rust performances.
So I believe that when you are that close in term of performances, you can assume that they all have the same performance, and that it should not be a decision driver whatsoever.
What I'd really like to see is benchmarks that compare the rust version to C.