The Rust compiler has gotten faster again
nnethercote.github.io
nnethercote.github.io
Edit:
> the constraints of the borrow checker make things like tree structures at least an order of magnitude harder to get right
The constraints of the borrow checker make those things more unlikely to compile without extra ceremony. The likelihood of getting them right is orthogonal from making the compiler "happy", even in Rust but specially in other languages. The way I've heard it described is that Rust is a language where you get the hangover first. It upfronts dealing with the error conditions of your problem space in a way that (you can argue) hinders the exploration phase, but that makes of a very quiet maintenance phase.
Pretty sure modern state of the art GCs, like the ones found in Java or .NET runtimes, are way more efficient than reference counting.
Reference counters have that unfortunate RAM access pattern where the counter is frequently updated from multiple threads concurrently. On modern processors, this means concurrent access to a cache line by different CPU cores. These cache coherency protocols are pretty slow. On many CPUs, reading a cache line recently modified by another core costs 300-500 clock cycles, even more expensive than a cache miss and roundtrip to system RAM.
What I don't agree with is the idea of taking Rust's ideas and putting them into manually-memory-managed, unsafe languages. We should be moving away from such languages as an industry.
sooo... ocaml?
You're describing Swift
But that only goes for reference types. For value types you're correct that both languages use mostly static memory management.
I guess in that sense you'd have to consider Rust as a gc'd language as well: the only difference really is that you have more fine-grained control over which mode of reference counting is being used for a given object.
Regarding C++ smart pointers, if you manually call them like in std::shared_ptr<>(), no.
If the runtime calls it for you like on C++/CX or compiler blessed types like _com_ptr_t, then surely.
> We present a formulation of the two algorithms that shows that they are in fact duals of each other. .... Using this framework, we show that all high-performance collectors (for example, deferred reference counting and generational collection) are in fact hybrids of tracing and reference counting.
...
> For every operation performed by the tracing collector, there is a corresponding "anti-operation" performed by the reference counting collector.
...
> We have shown that tracing and reference counting garbage collection, which were previously thought to be very different, in fact share the exact same structure and can be viewed as duals of each other.
But in practice I think modern swift uses inheritance very sparingly, and leans much harder on the protocol/extensions system, which is very well design imo
Reference counting is a GC algorithm, regardless how people sell it to the man on the street.
Additionally there is a whole set of politics how ARC had to be sold after the technical failure to make Objective-C GC implementation work without core dumps, due to the underlying C semantics.
Plus making retain/release calls automatic wasn't anything new as idea, VB and Delphi did it first with COM AddRef/Release.
However until certain C++ overloads don't give more love to memory-safe, garbage collected language or languages like Rust, that is better than nothing.
For example, I don't expect Windows team to ever lose their love for C++, NVidia moving from their C++ love for CUDA, or Metal shaders in something else.
Ah, and then many of those languages are keeping C++ around by building on top of GCC or LLVM.
So any improvement towards to make C and C++ safer is better than just using them as they are.
I sure hope not. Borrow checker has little to do with memory allocation/deallocation. It's there so that you can't have unprotected mutable shared state.
As an example, here is a video of David Pedersen creating a simple Tower service: https://www.youtube.com/watch?v=16sU1q8OeeI&t=945s
I found it intimidating how much you have to write to create a simple middleware.
Compared to C, and sometimes C++, there's generally less boilerplate in Rust. Compared to more traditional web languages, though, Rust will seem to have more boilerplate due to it's lower-level design.
https://github.com/rust-lang/rust/pull/88243
Rustc supports running with LLVM versions other than 13.0, which some distros enable, but the official builds of rustc all use LLVM 13.0, a pre-release version in 1.56.0, and the final in 1.57.0 onwards.
So far I managed to get basic serial coms working, but am waiting for some HAL so I can build a blinky LED.
But if most of your compiles are during development and debugging where optimization is less important, wouldn't it be nice to have super fast compilation during those stages? I don't know if any other compiled language comes close to Pascal in that regard.
Dynamic dispatch is faster to compile than static dispatch, but runtime performance differs. You can do dynamic dispatch in Rust, I think it could enable faster/smaller builds but at the cost of worst runtime performance.
Tradeoffs, Yada Yada.
Then we had to repeat it for HP-UX, Aix, Solaris, Windows NT/2000, in release and debug variants.
A release would be a day event, so fast to compile is relative.
You can even use it as a backend for the Nim (https://nim-lang.org/ ) compiler for subsecond builds of a modern language with various choices for automatic memory management.
Also, Borland Pascal / Delphi compilers weren't terrible at optimizing. And they often produced smaller executables.
Go and D are pretty comparable.