4 ms·
Years pass but I still prefer languages with reference counting over languages with proper GC. Main reasons for me: - Reference counting is deterministic (bar
by majke 10y ago
Years pass but I still prefer languages with reference counting over languages with proper GC.
Main reasons for me:
- Reference counting is deterministic (barring refcnt loops, which can usually be avoided by a careful programmer). Each run of the program will allocate/free memory in _exactly_ the same way.
- No latency spikes. "When GC kicks in, the latency must raise"
- This means it's way easier to understand the performance characteristics of code.
Having that in mind, there are couple of problems with refcnt:
- Cache spill. Increasing/decreasing a counter values in random places in memory kills cache. I remember one time I separated the "string object" data structure in python away from the immutable (!) string value (python has usually C struct object followed in memory by value blob). The python program suddenly went _way_ faster - immutable (readonly) string values in memory were close to each other, mutated refcnts were close to another. Everyone was happier
- When dealing with large data (binary blobs), refcnt programming languages have a tendency to copy over needed data. Copying over is in many cases slower.
In general I'd say it's the last point that is critical. The big question is less of "refcnt" vs "gc", but how to deal with binary blobs. "Copy over" pattern (C style) and newer version: "slices" (golang style) VS "proper GC" style of trying to guess how may pointers point to a blob.
- mortoray 10y agoThose are some of the points I'm considering as well when doing the memory management for Leaf. My desire to have predictable destructors is tough to reconcile in a tracing GC. I'm uncertain of what you mean with "copying the data over" in reference to large data. Surely it's still just the pointer being copied? Or are you speaking of things like `std::vector` in C++ that are value-copied by default?
- norswap 10y agoI tend to agree but don't overlook the downside of rfcnt loops. It's quite easy to introduce them (for instance, when creating closures in Objective-C), hence negating the big selling point of gc in the first place.
- david-given 10y agoRegarding latency spikes: that's not entirely true. If you drop the last reference to an object, then freeing that object can cause the last reference to other objects to be dropped, etc. So it's possible that dropping a reference can cause a large amount of work, which if it happens during a critical path can cause a latency spike. Particularly if finalisers are involved. If your object ownership graph is straightforward this isn't a problem, but if you have large objects with shared ownership it's very easy to be surprised here. (Used to work on a object-oriented operating system which used reference counting everywhere, and I discovered this the hard way.) I don't follow your comment about binary blobs?