On Wednesday, July 13, 2016 11:59:18 Miguel L via Digitalmars-d-learn wrote: > I am using a temporary dynamic array inside a loop this way: > A[] a; > for(....) > { > a=[]; //discard array contents > ... appends thousand of elements to a > ... use a for some calculations > } > > I would like to know which would be the best way to clear a > contents avoiding reallocations, as there seems to be lots of > garbage collection cycles taking place. > > The options would be: > > a=[]; > a.length=0; > a=null; > ... > any other? > > Can you help me please?
a = []; and a = null; both set the .ptr property of an array to null, and the length to 0. Setting the length to 0, just sets the length to 0. Regardless, appending after any of those operations is going to result in allocating memory, because the dynamic array has no unused memory to expand into. The GC determines whether it can append to a dynamic array without allocating based on whether that dynamic array's last element is the last element in the block of memory that the dynamic array refers to which has been used by any dynamic array. It does not keep track of how many arrays refer to the same memory block or where in the memory block they refer to. So, if the dynamic array that you're trying to append to does not refer to the last element in that block of memory which hasn't been used, then the GC has to assume that another dynamic array might refer to it. So, it won't expand into that memory and will instead reallocate. And because of that mechanic, in general, trying to "clear" a dynamic array doesn't work. However, if you are certain that there are no other dynamic arrays refering to the same memory, then you can tell the GC that by using assumeSafeAppend. e.g. a.length = 0; a.assumeSafeAppend(); And then the GC will think that the last element in a (which would be no element in this case) is the last used point in the block of memory pointed to by the dynamic array, and so it won't reallocate when you append. The big caveat here, of course, is that you have to be sure that there are no other dynamic arrays referring to the memory after a, or you'll be stomping on their memory when you append to a. But as long as you're sure that no other dynamic arrays refer to that memory, then you're fine. If you want an array type where you can clear out its elements and affect all other references to that array as well, then the built-in dynamic arrays won't cut it, and you'll need to use something like std.container.Array. If you haven't yet, I would advise reading http://dlang.org/d-array-article.html since it goes into detail on how D's dynamic arrays work - though it uses the wrong terminology and refers to the GC-allocated buffer that the dynamic array points to as if it were the dynamic array, and calls the dynamic array a slice, whereas the official terminology is that T[] is a dynamic array (no matter what memory it refers to), and if it's non-null, then it's a slice of whatever memory it points to. However, the memory that it points to is just the memory that it points to. It has no special name, even if it's GC-allocated. So, even if T[] is a slice of malloc-ed memory or of a static array, it's still a dynamic array (though in that case, appending to it will always reallocate, since the GC can't grow a dynamic array unless it points to memory allocated by the GC for dynamic arrays). But in spite of the slight terminology problem, it's a great article, and a must-read for anyone serious about D. - Jonathan M Davis