Builtin array and AA efficiency questions
Random D user via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Oct 15 14:00:36 PDT 2015
Thanks for thorough answer.
On Thursday, 15 October 2015 at 18:46:22 UTC, H. S. Teoh wrote:
>
> It adjusts the size of the allocated block in the GC so that
> subsequent appends will not reallocate.
>
So how does capacity affect this? I mean what is exactly a GC
block here.
Shrink to fit bit was confusing, but after thinking about this
few mins I guess there's like at least three concepts:
slice 0 .. length
allocation 0 .. max used/init size (end of 'gc block', also
shared between slices)
raw mem block 0 .. capacity (or whatever gc set aside (like
pages))
slice is managed by slice instance (ptr, length pair)
allocation is managed by array runtime (max used by some array)
raw mem block is managed by gc (knows the actual mem block)
So if slice.length != allocation.length then slice is not an mem
"owning" array (it's a reference).
And assumeSafeAppend sets allocation.length to slice.length i.e.
shrinks to fit. (slice.length > allocation.length not possible,
because allocation.length = max(slice.length), so it always just
shrinks)
Now that slice is a mem "owning" array it owns length growing
length happens without reallocation until it hits raw mem
block.length (aka capacity).
So basically the largest slice owns the memory allocation and
it's length.
This is my understanding now. Although, I'll probably forget all
this in 5..4..3..2...
> The thought that occurs to me is that you could still use the
> built-in arrays as a base for your Buffer type, but with
> various operators overridden so that it doesn't reallocate
> unnecessarily.
Right, so custom array/buffer type it is. Seems the simplest
solution.
I already started implementing this. Reusable arrays are
everywhere.
> If you want to manually delete data, you probably want to
> implement your own AA based on malloc/free instead of the GC.
> The nature of GC doesn't lend it well to manual management.
I'll have to do this as well. Although, this one isn't that
critical for me.
> The only thing I can think of is to implement this manually,
> e.g., by wrapping your AA in a type that keeps a size_t
> "generation counter", where if any value in the AA is found to
> belong to a generation that's already past, it pretends that
> the value doesn't exist yet. Something like this:
Right. Like a handle system or AA of ValueHandles in this case.
But I'll probably just hack up some custom map and reuse it's
mem. Although, I'm mostly doing this for perf (realloc) and not
mem size, so it might be too much effort if D AA is highly
optimized.
More information about the Digitalmars-d-learn
mailing list