www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is GC smart enough not to reallocate?

reply MMJones <MMJones mail.com> writes:
Suppose one has something like

class foo
{
    int[] x;
    void bar()
    {
       x = [];
    }
}

Does the GC trash the "cache" when calling bar or does it realize 
that it can use the same memory for x and essentially just 
shortens the array?

Is it equivalent to setting length = 0?

I'm a bit worried that setting a managed array to [] might cause 
a completely new reallocation, which is unnecessary and 
undesirable.
Jun 16 2016
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/16/16 9:54 AM, MMJones wrote:
 Suppose one has something like

 class foo
 {
    int[] x;
    void bar()
    {
       x = [];
    }
 }

 Does the GC trash the "cache" when calling bar or does it realize that
 it can use the same memory for x and essentially just shortens the array?
If you reassign x, the compiler does not know enough context to assume nothing else has a reference to x's old data. So no, it would not re-use that same data.
 Is it equivalent to setting length = 0?
Even this is not going to overwrite the data. You'd need to do: x.length = 0; x.assumeSafeAppend;
 I'm a bit worried that setting a managed array to [] might cause a
 completely new reallocation, which is unnecessary and undesirable.
Use assumeSafeAppend when you need to do this. BTW, x = [] is equivalent to x = null. So this is most certainly going to cause a new allocation on the next append. -Steve
Jun 16 2016
prev sibling parent John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 16 June 2016 at 13:54:11 UTC, MMJones wrote:
 Suppose one has something like

 class foo
 {
    int[] x;
    void bar()
    {
       x = [];
    }
 }

 Does the GC trash the "cache" when calling bar or does it 
 realize that it can use the same memory for x and essentially 
 just shortens the array?

 Is it equivalent to setting length = 0?

 I'm a bit worried that setting a managed array to [] might 
 cause a completely new reallocation, which is unnecessary and 
 undesirable.
To prevent confusion, here's a related example: void foo() { int[] x = [1,2,3]; x = [4]; } in theory, the first allocation (for [1,2,3]) could be avoided. It wouldn't be the GC doing it though, it would just be the optimiser eliminating the redundant initialisation of x. However: class C { int[] x; this() { x = [3,2,1]; } void foo() { x = [0]; } } auto bar() { auto c = new C; auto localX = c.x; c.foo(); return localX; } the initialisation of c.x is no longer redundant, because the memory is referenced by localX, so a new allocation is necessary in foo. P.S. remember that D's arrays/slices aren't "managed" as such. Only the memory backing them is managed, and then only if the memory was allocated by the GC.
Jun 16 2016