On Sunday, December 18, 2011 00:15:40 Andrei Alexandrescu wrote: > On 12/17/11 7:52 PM, Jonathan M Davis wrote: > > The only reason that I can think of to use a reference-counted struct > > instead of a class is becuse then it's easier to avoid the GC heap > > entirely. Almost all of a container's memory is going to end up on the > > heap regardless, because the elements almost never end up in the > > container itself. > > Being on the heap is not the main issue. The main issue is the data > becoming garbage once all references are gone. > > > They're in a dynamic > > array or in nodes or something similar. So, whether the container is > > ref- > > counted or a class is almost irrelevant. > > I think this argument is starting off the wrong premise, and is already > wrong by this point, so I skipped the rest. Am I right?
My initial take on this is that the primary difference between a final class and a ref-counted struct is the fact that the class is on the heap and needs no ref-counting, whereas the struct is no the stack and has to do ref-counting, and everything else is the same regardless, since the memory for the container has to go on the heap regardless (be it the GC heap or wherever the allocator puts it). But what you're bringing up is that in the case of the class, everything in the container stays around until it's garbage collected, whereas in the case of the struct, it goes away as soon as the ref-count hits zero? I hadn't thought of that. But if we're talking about the GC heap, since most of the internals are going to be on the heap in either case, with the only difference being the container itself and its value type member variables. However, once you use a custom allocator (say one that uses malloc and free), then in the struct case, everything gets cleaned up as soon as the ref-count hits zero, whereas with the class it sits around until the container itself is collected - assuming that the class itself is on the GC heap. If it was using the malloc-free allocator, then it would be around until it was manually freed by the allocator. I don't know. That is certainly food for thought. My natural inclinition is to just make it a class, since it's a reference type, and then you don't have to worry about the cost of ref-counting or have any confusion over whether the container is a reference type or not. But if there's any real performance advantage in using ref-counted structs due to something to do with memory management, then that would be highly valuable. If no custom allocators are used, then I'd expect the struct to be worse off, since it has the cost of being copied as well as the cost of ref-counting, whereas the only cost in passing the class around is copying it's reference, and other than the few member variables that the container has, there's no difference in how long the memory in the container sticks around. It has to wait for the GC in either case. It's only when a custom allocator which could free the memory as soon as the ref-count hits zero comes into play that it makes a difference, in which case the struct would probably be more efficient. Unless I'm missing something? It certainly doesn't seem like an easy call. - Jonathan M Davis
