Ah missed your post before replying to H.S. Teoh (I should
refresh more often).
Thanks for reply.
On Thursday, 15 October 2015 at 19:50:27 UTC, Steven
Schveighoffer wrote:
Without more context, I would say no. assumeSafeAppend is an
assumption, and therefore unsafe. If you don't know what is
passed in, you could potentially clobber data.
In addition, assumeSafeAppend is a non-inlineable, runtime
function that can *potentially* be low-performing.
Yeah I know that I want to overwrite the data, but still that's
probably a lot of calls to assumeSafeAppend. So I agree.
instance, you call it on a non-GC array, or one that is not
marked for appending, you will most certainly need to take the
GC lock and search through the heap for your block.
What does marked for appending mean. How does it happen or how is
it marked?
The best place to call assumeSafeAppend is when you are sure
the array has "shrunk" and you are about to append. If you have
not shrunk the array, then the call is a waste, if you are not
sure what the array contains, then you are potentially stomping
on referenced data.
So assumeSafeAppend is only useful when I have array whose length
is set to lower than it was originally and I want to grow it back
(that is arr.length += 1 or arr ~= 1).
An array uses a block marked for appending, assumeSafeAppend
simply sets how much data is assumed to be valid. Calling
assumeSafeAppend on a block not marked for appending will do
nothing except burn CPU cycles.
So yours is not an accurate description.
Related to my question above.
How do you get a block not marked for appending? a view slice?
Perhaps I should re-read the slice article. I believe it had
something like capacity == 0 --> always allocates. Is it this?
A.3) If A.2 is true, are there any conditions that it reverts
to
original behavior? (e.g. if I take a new slice of that array)
Any time data is appended, all references *besides* the one
that was used to append now will reallocate on appending. Any
time data is shrunk (i.e. arr = arr[0..$-1]), that reference
now will reallocate on appending.
Thanks. IMO this is very concise description of allocation
behavior.
I'll use this as a guide.
So when to call really sort of requires understanding what the
runtime does. Note it is always safe to just never use
assumeSafeAppend, it is an optimization. You can always append
to anything (even non-GC array slices) and it will work
properly.
Out of curiosity. How does this work? Does it always just
reallocate with gc if it's allocated with something else?
This is an easy call then:
array.reserve(100); // reserve 100 elements for appending
array ~= data; // automatically manages array length for you,
if length exceeds 100, just automatically reallocates more data.
array.length = 0; // clear all the data
array.assumeSafeAppend; // NOW is the best time to call,
because you can't shrink it any more, and you know you will be
appending again.
array ~= data; // no reallocation, unless previous max size was
exceeded.
Thanks. This will probably cover 90% of cases.
Usually I just want to avoid throwing away memory that I already
have.
Which is slow if it's all over your codebase.
Like re-reading or recomputing variables that you already have.
One doesn't hurt but a hundred does.
B.1) I have a temporary AA whose lifetime is limited to a
known span
(might be a function or a loop with couple functions). Is
there way to
tell the runtime to immeditially destroy and free the AA?
There isn't. This reminds me, I have a lingering PR to add
aa.clear which destroys all the elements, but was waiting until
object.clear had been removed for the right amount of time.
Perhaps it's time to revive that.
Should array have clear() as well?
Basically wrap array.length = 0; array.assumeSafeAppend();
At least it would then be symmetric (and more intuitive) with
built-in containers.
-Steve