std.container and classes

Jonathan M Davis jmdavisProg at gmx.com
Sat Dec 17 23:42:58 PST 2011


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


More information about the Digitalmars-d mailing list