5 ms·
Ok but in rust those pointers can just be borrowed obviating the need for gc at all.
by asimpletune 7y ago
Ok but in rust those pointers can just be borrowed obviating the need for gc at all.
- masklinn 7y agoGiven it's a cache the entries would not have an existing natural owner… except for the cache itself. There would be no need for a GC to traverse the entire map, but that's because rust doesn't use a GC.
- falcolas 7y agoWhile Rust does not have a discrete runtime GC process, it does utilize reference counting for dynamic memory cleanup. So you could argue that they are still going to suffer some of the downsides of a GC'ed memory allocation. Some potential issues include non-deterministic object lifespan, and ensuring that any unsafe code they write which interacts with the cache does the "right thing" with the reference counts (potentially including de-allocation; I'm not sure what unsafe code needs to do when referencing reference counted boxes).
- masklinn 7y ago> While Rust does not have a discrete runtime GC process, it does utilize reference counting for dynamic memory cleanup. That's so misleading as to essentially be a lie. Rust uses reference counting if and only if you opt into it via reference-counted pointers. Using Rc or Arc is not the normal or default course of action, and I'm not aware of any situation where it is ubiquitous. > So you could argue [nonsense] No, you really could not.
- mcguire 7y agoOn the other hand, Rust's RAII management model behaves similarly to a reference counting system where the counts are limited to 0 and 1 (well, for a loose approximation of the 0 state), right?
- steveklabnik 7y agoSome people say this, but I think it's misleading; refcounting can make things live longer, but the borrow checker cannot.
- Jweb_Guru 7y agoWell, with ownership, a move can make things "live" longer, I guess.
- steveklabnik 7y agoYou're not wrong. I just think there's enough difference that the analogy doesn't really work.
- ta20200202 7y agoRAII for references (pointers) is a no-op. If the cache returns references to the data in its own array there is no overhead.
- falcolas 7y agoI was making an assumpotion that using a vector of ARC<T> would be the best way to handle a global LRU cache. Perhaps I should have specified it, but it seemed pretty obvious. Sorry if it wasn’t. If there’s a better way to handle a global LRU cache, I’m all ears.
- jhgg 7y agoAssuming only one thread at a time needs to access the LRU cache (not hard with the shared-nothing message passing architecture which we employ here), the lifetime of the object being checked out from the cache is able to be understood at compile time, and we can just use the borrow checker to ensure that it remains that way (we've got a mutable reference to the LRU, and we can use that to get a mutable reference to an object within the LRU. By the time the function that is mutating the data in the LRU finishes, the references to the objects must be dead (the borrow checker will enforce that.) Since all this information is available during compile time, runtime ref-counting (via rc/arc) is not necessary. This is made possible by rust's memory model, where it understands ownership of data, and the lifetime of each reference that's being taken from that owned data. This means that the compiler can statically determine how long an object needs to live, and that references to the object don't outlive the owned data. For use-cases where the lifetime of references are able to be statically understood, an arc/rc is not required. This blog-post goes into it in much better detail than I can: https://words.steveklabnik.com/borrow-checking-escape-analysis-and-the-generational-hypothesis https://words.steveklabnik.com/borrow-checking-escape-analys...
- falcolas 7y agoYes, I'm quite familiar with rust's borrow checking model. I've programmed some in rust, and the rest has been beaten into my head quite thoroughly by Rustaceans. I don't care for Rust, but I understand it. Locking on one thread at a time seems like a pretty obvious performance flaw. It just doesn't seem like an appropriate design for the given workload (lots of requests, lots of stored items, largely write-only (except for its position in the queue)). It would make a lot more sense to grant multiple threads access the LRU at any given time. And early optimization and all that aside, creating the LRU in such a way that it can be easily restricted to one thread or opened up makes the most sense to me. Otherwise, you get to re-write the LRU (and all the code which accesses it) if it should be identified as a bottleneck. Of course, I'm not responsible for the code or truly involved in the design process, so my perspective may be limited.
- iknowstuff 7y agoI think you're confusing Rust's ownership model with Swift's ARC. Rust doesn't do reference counting unless you use Rc<T> or Arc<T>.
- falcolas 7y agoGiven the model of memory we are discussing (a global per-process LRU cache), that’s exactly what I was discussing using. Unless there’s another way to handle such global caches.