4 ms·
Two things jump out at me: 1. Automatic reference counting is a really good alternative to GC. It takes a little bit more book-keeping, but the performance ch
by skohan 9y ago
Two things jump out at me:
1. Automatic reference counting is a really good alternative to GC. It takes a little bit more book-keeping, but the performance characteristics are predictable since allocations/frees are handled along the way. Many GC implementations require execution to be halted while the reference graph is traced, which makes it a non-starter for applications trying to deliver predictable real-time performance.
2. Most of the limitations in Rust you're lamenting are there to ensure that your code is safe and performant. Rust requires adapting to very different design-patterns than you might be used to to get these benefits: if something is hard to do in Rust it's probably an anti-pattern with respect to memory performance or safety. Then again if performance isn't your main concern, maybe you don't need Rust.
- Koshkin 9y ago> Automatic reference counting is a really good alternative to GC 1) GC is lazy, whereas RC is eager; 2) the use of "pure" RC may lead to memory leaks.
- vlovich123 9y agoMemory leaks occur in GC too.
- pcwalton 9y agoAutomatic reference counting is just a slow form of GC.
- widdershins 9y agoYes, slower than modern GC, but predictable and deterministic. Note that the parent comment never claimed it was faster, just that it avoids 'stop the world' which can be a problem in realtime contexts (e.g. games, audio).
- jmgao 9y agoReference counting isn't inherently more predictable than tracing garbage collection. Take the example where your thread is the last one to deref a gigantic object graph. You're stuck holding the bag on traversing the entire graph and destructing it all at once, when a tracing gc could do it piecemeal (and on a dedicated background thread, instead of on your real worker threads).
- derefr 9y agoIf objects that hit zero refs have their reference pushed into the queue of a dedicated GC thread, is that not still called RC, or is that called something else?
- papaf 9y agoResearchers tend to call them Reference Counted Garbage Collectors. Here is a random example that actually recommends the opposite (RC in old generations, mark and sweep in the young generation): https://link.springer.com/chapter/10.1007/3-540-36579-6_14 https://link.springer.com/chapter/10.1007/3-540-36579-6_14
- BlackFingolfin 9y agoReference counting can also lead to big cascades of objects being freed, which can make it impractical in realtime context as well. This makes RC useless for systems which have hard constraints here (e.g. automotive). And of course, once you are multi-threaded, you can more or less forget about "predictable and deterministic" with RC, too. In contrast, there are real time capable garbage collectors.
- SolarNet 9y agoEhhh, except that rust's borrowing system is a really great aid to prevent those sorts of things. And, one can easily make a thread responsible for deallocating the cascading objects. The point being that reference counting allows one more control over how deallocation is done. Besides, the real time capable garbage collectors are basically just backed in implementations of exactly that. With reference counting, it can be written in the language itself, rather than as a tunable external part of the implementation, which is useful.
- nabla9 9y agoReference counting is a form of GC. The problem with reference counting is that it don't work with recursive structures and counters may overflow. Overflow or reaching some max value and returning runtime error are both problems.
- vlovich123 9y agoOn 64-bit platforms you're not going to overflow the counter. 32-bit platforms these days are embedded & they too are highly unlikely to overflow the counter. Recursive structures are a problem although in my experience you can usually just alter the ownership rules a bit instead. FWIW there's a Rust GC library that provides opt-in GC for when you need it. https://github.com/Manishearth/rust-gc https://github.com/Manishearth/rust-gc
- dmitrygr 9y agoif something is hard to do in Rust it's probably an anti-pattern with respect to memory performance or safety. Oh? Tell me, how many lines of Rust does this take you? struct Task { struct Task *next; struct Task *prev; struct TaskRegs regs; //other shit here } Or are doubly-linked lists antipatterns now?
- steveklabnik 9y agostruct Task { next: *mut Task, prev: *mut Task, regs: TaskRegs, // other shit here } is the direct translation. > Or are doubly-linked lists antipatterns now? They're often not what you want, yes. But if you are in that situation, in the worst case you're in the same place as C, and you can write the Rust the same way if you'd like.
- dmitrygr 9y agoDoubly linked lists are impossible in safe rust by definition since the only safe way to modify a memory location is via a &mut reference. And Rust guarantees that that any memory location can only be pointed to by only one &mut reference. A doubly linked list by definition has two pointers pointing to each node, so no, your example will not work.
- steveklabnik 9y agoThe example uses raw pointers, which aren't safe Rust. Note the *mut, not &mut. It's the direct translation of your C, which is why I mentioned that specifically.
- dmitrygr 9y agoIf it has no protections then why even use rust? You cannot both claim safety and then claim versatility by abandoning said safety. Because without your claimed safety, I might as well use C and not do battle with my compiler.