On Thursday, 30 July 2020 at 16:33:22 UTC, Ali Çehreli wrote:
On 7/30/20 8:58 AM, wjoe wrote:

         b.reserve(n);
         b.length = n;

There may be something that I don't know but I think assigning to the .length property alone should be the same as reserving and then assigning.

reserve is supposed to make sure no memory will be allocated as elements are added.

So whichever instruction is redundant depends on whether I want an array of length n, or an empty array that can grow to at least n elements without reallocation.

This article is considered a must-read for understanding what is going on behind the scenes:

  https://dlang.org/articles/d-array-article.html

I tried to introduce the concept of slices "sharing elements" as well as how .capacity is used to determine whether sharing will be terminated, here:

  http://ddili.org/ders/d.en/slices.html#ix_slices..capacity

Ali

These resources are great. Thanks.



On Thursday, 30 July 2020 at 16:55:35 UTC, Steven Schveighoffer wrote:
On 7/30/20 11:58 AM, wjoe wrote:
Also there's .capacity - is that equivalent to reserve ?

Capacity tells you how many total elements the current reserved space can hold. If the array is not appendable, then this returns 0.

So .capacity can't be assigned a value like length to reserve the RAM ?

Another curiosity I noticed is that the docs say that the runtime tries to resize in place, however:

b = b[0..$-1]; if length==1 seems to collect the memory at once because if it's immediately followed by b.length = 1; or b ~= someT; b.ptr points to a new address.
Why ?

Because you would be overwriting the data already in the array.

For example:

auto a = b;
b = b[0 .. $-1];
b ~= someT;

If that last line is done in-place, then it overwrites a[$-1].

So this is a case of sharing being terminated ?

If you know that it's OK to do this, then you should call assumeSafeAppend on the array (which will adjust the "used" space down to the current array).

This array is a private array of pointers to released structs - technically a stack. Every time a new element is requested, the most recently released element would be taken off the stack and be set to the new data until the stack was exhausted. Expired structs are put back into (appended to) the array for reuse. When the length of the array == 0, upon releasing a struct, this array is reallocated which isn't supposed to happen. It should just grow like it did with length > 1.
assumeSafeAppend should accomplish that :)

I know that b=b[0..0]; is equivalent to b = null;

No, if slicing b to b[0 .. 0], b.ptr does not change. b = null sets the pointer to null. In the former case, if you called assumeSafeAppend on it, then it could append in-place at that point. With the null pointer, it would reallocate.

-Steve

I could swear just a few weeks ago there was someone asking how to tell if an array was null or of length 0 and an answer was that it's the same and can't be distinguished so I assumed that assigning a slice of 0 length is the same as setting the array to null because the result is the same as a 0 length array.
Thanks for the explanations and corrections.



bachmeier, a picture tells more than a thousand words. Your illustration is very comprehensive. Thanks :)


Thank you everyone, your input is very much appreciated :)

Reply via email to