Rust compilation is not intrinsically slow; better IR and more incremental compilation can and will improve it. Incremental compilation (only changed files, not crates) is 7 years in making though.
[1]: https://prev.rust-lang.org/en-US/faq.html#why-is-rustc-slow
Other reasons:
- suboptimal LLVM IR code, as you mentioned, and other tech debt
- the preferred strategy of monomorphising generics is fast at runtime, but slow to compile, using trait objects is faster
- the complex type system of course also plays a part
- LLVM itself is of course not optimized for Rust
I'm not sure it was a "bad decision" if it was something that can be addressed after the fact and allowed them to ship working software more quickly.
The vast majority of the popular projects I am aware of have this kind of technical debt, likely due to survivorship bias. Project teams that refuse to take on technical debt are rarely successful enough to become popular.
Maybe we are giving Rust developers computers that are too fast. ;-)
OTOH, it's always wise to design for the future, so it also makes sense to give Rust developers beefy server grade hardware so they can play with SIMD pipelines and all those extra cores and threads, because that's what workstations will be a couple years from now.
It is only a matter of time, until GCC and clang finally catch up.
Shouldn't this be enough? Or does it require explicitly including the precompiled header whereas VC++ has magic to make that transparent?
(Same reason why C with typedefs is slower to compile than plain C, why C++ is slower, etc)
(that and cargo dependencies, etc - also C compilers have some +30yrs of optimizations)
A full Rust kernel might be neat. A compromised Rust driver inside of a C kernel is never going to be the default choice.
The actual driver code is pretty readable, see https://lwn.net/Articles/863459/.
May I interest you in Redox? https://www.redox-os.org/
Obviously very different than Linux.
There's been multiple passes at making the Rust compiler faster. It'll happen. There's a GCC-based Rust implementation in the works too.
> The main difference between Rust and other languages is that it does some more (but not all [2]) safety checks at compile time rather than at runtime. It also allows you to avoid GC, but does not provide you any memory safety over GC. Rust's borrow checker allows you to statically prove that references are live [3]; a GC simply avoids deallocating any memory that has a live reference to it (on the other hand, a GC can ensure that references remain live even where this is hard or impossible to prove statically). The end result is the same with respect to memory safety (the reason some people want to avoid GC is for performance reasons, not memory safety).
> The main difference between ARC and Nim GCs is that ARC is fully deterministic - the compiler automatically injects destructors when it deems that some variable (a string, sequence, reference, or something else) is no longer needed. In this sense, it’s similar to C++ with its destructors (RAII). To illustrate, we can use Nim’s expandArc introspection (will be available in Nim 1.4).
> This shows one of the main ARC features: scope-based memory management. A scope is a separate region of code in the program. Scope-based MM means that the compiler will automatically insert destructor calls for any variables which need a destructor after the scope ends. Many Nim constructs introduce new scopes: procs, funcs, converters, methods, block statements and expressions, for and while loops, etc.
> ARC also has so-called hooks - special procedures that can be defined for types to override the default compiler behaviour when destroying/moving/copying the variable. These are particularly useful when you want to make custom semantics for your types, deal with low-level operations involving pointers, or do FFI.
You can always make it your own personal default with older versions (e.g. nim-1.6), by editing your $HOME/.config/nim/nim.cfg to say so or doing similar on per project/file basis.
Rust also uses the same mechanisms to get compile time thread safety with full memory sharing between threads. Does any other language that doesn't have a global lock, throwing away most of the advantage, have that? There are actual new and interesting advantages to the compile time ownership model.
A minor advantage on the age of microservices and OS IPC to shared external resources.
Sendable doesn't apply when those threads are accessing shared external resources.
If you want fully lock-free it might be possible to prove that with extensions like Liquid Haskell, via Linear types, and is definitely easier to prove with a theorem prover than it is, generally, for C++ code. Not sure about Rust though I realize quite a lot of its moving parts have already been formalized which is super cool.
There are reasons for using Rust but it's not the only game in town. And GC doesn't automatically mean pessimistic performance.
Rust is a huge, huge win for that reason. It allows for code written in a Lisp/OCaml/Nim style that's memory safe without any additional overhead.
Ada, Delphi, OCaml, C#/F# (.NET Native / Native AOT), D, Nim,...
For everything else regarding concurrent access to shared data out of process, they are on the same foot.
Ada didn't took off, because of several reasons, price of compilers, on UNIX it was an additional SKU on top of the respective developers SDK that already offered C and C++ in the box, 1980's mainstream hardware wasn't able to cope with it, most OS vendors outside UNIX decide to migrate from their toolchains into C and C++, so again additional money on top of the OS SDK.
Early Ada compilers had expensive licensing and required expensive hardware to run.
By the time GNAT was added to GCC, C++ had already taken over most of the spaces that were not Ada exclusive (meaning safety critical / defense / aerospace niches where either Ada was once mandated or has thrived in despite the original high costs).
Except most of C# ecosystem relies on classes and GC. A lot of these problems are caused by overuse of GC-ed classes, and their ease of use.
C and C++ aren't immune to heap abuse as well.
You do on C# just like on them, think about data structures, and avoid heap during render loop
They still ran into limitations where basically "This would be a lot easier if we didn't have GC".
tr;dl — I’d really prefer the option to determine when I’d like GC, as opposed to dodging the collector to avoid performance hits, hot code can default to manual. Probably not a realistic ask, but it could work.
Fair enough. If SS14 used D maybe they wouldn't have these problems.
D and early Rust (pre 0.2, like alpha alpha) had that. Problem is you split your community in two. You get a version of "What GC-color is your function/lib?".
It's a tradeoff for some domains - allow no GC bypass you're going to run into nigh insurmountable performance cliff.
Allow GC as opt-in and you run into issue of splitting your APIs in two.
"This would be a lot easier if we didn't have malloc()/free()", basically.
In any case Sony, Nintendo and Microsoft have been doing graphics stuff with C# for their platforms, although they could have kept being pure C++.
Also we shouldn't silo ourselves into only C# as discussion point, Go, D, Nim, Swift, Eiffel are also possible examples.
Well, not really. It's just some libraries like YamlDotNet copy waaaay more than needed and it shows in serialization. They mostly minimized calling YamlDotNet, but true solution would be a zero copy parser.
Other issue was HashSet operation like Clear had huge impact. Think they replaced those with arrays.
Third issue was something about flecs and archetype ECS. I don't know if it was a jest, but they mentioned changing GC layout or rewriting GC.
Points is, they now face a steep performance cliff. The only way out of it is through sheer effort.
So no, it's not anti-GC religion. Some domains and GC really badly mix.
https://www.microsoft.com/en-us/research/project/singularity
I believe the point the author is making is that other languages provide better safety than C and have faster compile times than Rust, therefore Rust should be able to improve its compile times.
Ada with SPARK 2014 formal proofs, for your other part of the remark.
What you may want to try to avoid is complex and non-deterministic GC, which makes it harder to reason about.
We should aspire to make it as fast but in the short term a slower compiler in exchange for less CVEs and random buffer overrun crashes seems like a reasonable trade off to me.
Distributions such as Fedora offer build infrastructure[1] that you can use to compile packages to use in your system for testing if you feel your local hardware isn't powerful enough.
[1]: https://copr.fedorainfracloud.org