I love how it shows that you can have both performance and safety without jumping through hoops. The little details of memory management really shape how we end up writing code, often without even noticing. Rust makes it possible to get close to the hardware while still keeping you out of the usual trouble spots. It’s one of those things you appreciate more the longer you use it
While safe Rust may be relatively simple to write, and certainly easier to write than safe C, this article has someone added to my belief that unsafe Rust is far too difficult to write. Perhaps some of this is deliberate, as a kind of defence mechanism against people using it willy-nilly, it still seems over-designed.
I gave up half way through. The constant description of deep emotional feelings when it comes to something as sober as data types in the rust standard library make this rather hard to read. It is difficult to untangle the point the author is trying to make from the constant bombardment with deep emotional writing.
I'm sure all these layers are good engineering and provide meaningful safety guarantees, but it sure makes the code harder to understand if you want to see how things are implemented.
Another example, I was trying to see how i64::isqrt is implemented, but first you have to wade through layers of macros
Because this is focused on how the data structure works it doesn't mention lots of nice API design choices in Rust.
The one I particularly want to call out because it came up this morning is providing both Vec::reserve and Vec::reserve_exact
Vec::reserve lets us hint about our upcoming capacity expectations without damaging the O(1) amortized growth which is the whole point of this collection type, but it can waste some memory to achieve this. This is probably what you want in most code.
Vec::reserve_exact is a more narrow idea - we can hint about the ultimate capacity needed, if we're wrong and later need more capacity this has a significant performance cost because we thew away the amortized growth promise to get this, but we don't waste memory.
C++ only provides the equivalent of Vec::reserve_exact which makes this a footgun but if you use this call when you really needed the other one you trash your perf, as a result of which people teaching C++ tend to just say don't use reservation to uh, reserve capacity, but now you're leaving perf on the table so that's not great.
Reserve(reserve_exact in rust lingo) as a concept doesn't throw away amortized growth promise, so this entire post makes no sense.
You would need a very shitty implementation to achieve anything close to what you are describing(perhaps only allocating in powers of 2), and even then it would recover fairly quickly.
It is not clear, does compiler explicitly knows about properties of `NonNull` (for example, that it has neutral value to collapse `Option<NonNull<T>>`), so it is part of compiler, or it is expressed in type system, so it is part of standard library?
The explanation of `Unique` is a bit botched. `Unique` was originally intended to convey uniqueness in the sense of `noalias`, so that more compiler optimizations are possible similar to what happens around mutable references. This is what the article seems to suggest is going on .
But this is wrong, it is no longer the case that `Unique` implies any extra optimizations, since it was since recognized that having these optimizations on a low-level unsafe building block is actually undesirable. Further, the `as_ref` functions mentioned in the article are not used by `Vec`'s internals. They are anyways only marked unsafe because they create references, not because of anything special with `Unique`.
Nowadays, all that `Unique` does is interact with `dropck` in a quirky way, the "exception to the exception." It is quite complicated and I always have to read up on it. It is explained in the Rustonomocon, in the "Click here to see why" section of this chapter: https://doc.rust-lang.org/nomicon/phantom-data.html#an-excep...
16 comments
[ 0.23 ms ] story [ 126 ms ] threadHere's what it looked like at 1.0.0: https://github.com/rust-lang/rust/blob/1.0.0/src/libcollecti...
Another example, I was trying to see how i64::isqrt is implemented, but first you have to wade through layers of macros
The one I particularly want to call out because it came up this morning is providing both Vec::reserve and Vec::reserve_exact
Vec::reserve lets us hint about our upcoming capacity expectations without damaging the O(1) amortized growth which is the whole point of this collection type, but it can waste some memory to achieve this. This is probably what you want in most code.
Vec::reserve_exact is a more narrow idea - we can hint about the ultimate capacity needed, if we're wrong and later need more capacity this has a significant performance cost because we thew away the amortized growth promise to get this, but we don't waste memory.
C++ only provides the equivalent of Vec::reserve_exact which makes this a footgun but if you use this call when you really needed the other one you trash your perf, as a result of which people teaching C++ tend to just say don't use reservation to uh, reserve capacity, but now you're leaving perf on the table so that's not great.
You would need a very shitty implementation to achieve anything close to what you are describing(perhaps only allocating in powers of 2), and even then it would recover fairly quickly.
Same question about other «signal» types.
I didn't know this about Rust. That's awesome.
But this is wrong, it is no longer the case that `Unique` implies any extra optimizations, since it was since recognized that having these optimizations on a low-level unsafe building block is actually undesirable. Further, the `as_ref` functions mentioned in the article are not used by `Vec`'s internals. They are anyways only marked unsafe because they create references, not because of anything special with `Unique`.
Nowadays, all that `Unique` does is interact with `dropck` in a quirky way, the "exception to the exception." It is quite complicated and I always have to read up on it. It is explained in the Rustonomocon, in the "Click here to see why" section of this chapter: https://doc.rust-lang.org/nomicon/phantom-data.html#an-excep...