Builtin array and AA efficiency questions
Mike Parker via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Oct 15 22:05:17 PDT 2015
On Thursday, 15 October 2015 at 21:48:29 UTC, Random D user wrote:
>> 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?
There are a handful of attributes that can be set on memory
allocated by the GC. See the BlkAttr enumeration in core.memory
[1]. Under the hood, memory for dynamic arrays (slices) is marked
with BlkAttr.APPENDABLE. If an array pointing to memory not
marked as such, either manually allocated through the GC, through
malloc, or another source, then assumeSafeAppend can't help you.
capacity tells you how many more elements can be appended to a
dynamic array (slice) before an allocation will be triggered. So
if you get a 0, that means the next append will trigger one.
Consider this:
int[] dynarray = [1, 2, 3, 4, 5];
auto slice = dynarray[0 .. $-1];
slice points to the same memory as dynarray, but has 4 elements
whereas dynarray has 5. Appending a single element to slice
without reallocating will overwrite the 5 in that memory block,
meaning dynarray will see the new value. For that reason, new
slices like this will always have a 0 capacity. Append a new item
to slice and a reallocation occurs, copying the existing elements
of slice over and adding the new one. This way, dynarray's values
are untouched and both arrays point to different blocks of memory.
assumeSafeAppend changes this behavior such that appending a new
item to slice will reuse the same memory block and causing the 5
to be overwritten. Normally, you don't want to use it unless you
are sure there are no other slices pointing to the same memory
block. So it's not something you should be using in a function
that can receive an array from any source. That array might share
memory with other slices, the block might not be appendable, you
have no idea how the slice is actually used... just a bad idea.
When you have complete control over a slice and know exactly how
it is used, such as an internal buffer, then it becomes a useful
tool.
[1] http://dlang.org/phobos/core_memory.html#.GC.BlkAttr
More information about the Digitalmars-d-learn
mailing list