std.container and classes
Jonathan M Davis
jmdavisProg at gmx.com
Sun Dec 18 20:12:57 PST 2011
On Sunday, December 18, 2011 02:46:01 Andrei Alexandrescu wrote:
> If this is a new notion, it might take a while for all of its aspects to
> sink in. I'm not saying that to be smug - reference counting vs. other
> methods of collecting garbage is definitely a difficult topic on today's
> architectures, and I can say at least it took me quite a while to build
> some reasonable mental model of the related tradeoffs.
After thinking about this a bit, I don't think that custom allocators are
really going to work with classes very well. Unless you allocate the entire
class with the custom allocator (as opposed to just telling the container to
use the custom allocator), the memory won't be cleaned up until the object is
collected by the GC (even though it's using a custom allocator to allocate its
internals), in which case, what does the custom allocator really buy us? So,
the idea of just passing the allocator to the container doesn't seem to cut it
for a class. The object itself needs to be allocated with the custom
allocator. On top of that, if you're allocating the container with a custom
allocator, doesn't that risk issues like what the to-be-deprecated scope
modifier causes? You practically end up having to wrap the class in a struct
anyway, in which case, what's the point of using a class?
Just in general, it's much harder to control the memory if the container is a
class rather than a struct. With a struct, you can do pretty much whatever you
want with the memory. Its lifetime is strictly controlled, which gives much
greater opportunites to optimize its memory usage. With a class, it's going to
be difficult to completely divorce the container from the GC in a clean manner.
With a struct, we could easily make the default not use the GC at all, which
would make the default use of the containers much more efficient. You also
wouldn't have to worry about creating the container itself with an allocator
and all of the potential issues that that brings.
I don't particularly like the idea of the cost of passing the container around
as a struct (since it's few member variables will have to be memcopied and the
ref-counting will have to be done), but that's not a huge cost (though it _is_
a pervasive one), and I'm begginning to think that it's a necessary one if we
want containers to be able to properly and efficiently manage their own memory.
Depending on the use case, the benefits from the containers being able to fully
manage their own memory without the programmer having to do anything special
could easily outweigh the additional cost of passing a struct around. And if
ranges over such containers are passed around more frequently than the
containers themselves (as I would expect), then the minor cost of passing the
container around is even less of a big deal, since it would primarily be the
ranges being passed around.
So, I'm beginning to think that we're going to have to go the struct route.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list