digitalmars.D - Is GC smart enough not to reallocate?
- MMJones (16/16) Jun 16 2016 Suppose one has something like
 - Steven Schveighoffer (11/25) Jun 16 2016 If you reassign x, the compiler does not know enough context to assume
 - John Colvin (36/52) Jun 16 2016 To prevent confusion, here's a related example:
 
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
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
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








 
 
 
 Steven Schveighoffer <schveiguy yahoo.com> 