www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - AA clear property

reply "Alex_Dovhal" <alex_dovhal yahoo.com> writes:
Hi, D have "clear" property for arrays and AA, but I failed to find it's 
description in docs. Where it's? 
Nov 05 2011
next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
Am 05.11.2011, 21:30 Uhr, schrieb Alex_Dovhal <alex_dovhal yahoo.com>:

 Hi, D have "clear" property for arrays and AA, but I failed to find it's
 description in docs. Where it's?

Are you this Alex? http://aichallenge.org/forums/viewtopic.php?f=21&t=1315#p10776 As I understand it this function is defined in object_.d which is always imported by default and can be called on an (associative) array through a mechanism called "universal function call", that matches the part before the dot with the first parameter of the function. This only works for arrays. So I believe it is a free function (to invalidate/finalize a variable) and not a property of an array at all.
Nov 05 2011
parent reply "Alex_Dovhal" <alex_dovhal yahoo.com> writes:
"Marco Leise" <Marco.Leise gmx.de> wrote:
 Are you this Alex?

 As I understand it this function is defined in object_.d which is always 
 imported by default and can be called on an (associative) array through a 
 mechanism called "universal function call", that matches the part before 
 the dot with the first parameter of the function. This only works for 
 arrays. So I believe it is a free function (to invalidate/finalize a 
 variable) and not a property of an array at all.

Thanks for clarification. So now my question and task changes. Is there a way to reuse previous memory occupied by AA, when I need to change all of it element? E.g. for dynamic arrays it's possible to make: dyn_arr.length = 0; assumeSafeAppend(dyn_arr); fill_new_values(dyn_arr);
Nov 05 2011
parent reply "Alex_Dovhal" <alex_dovhal yahoo.com> writes:
"Marco Leise" <Marco.Leise gmx.de> wrote:
 No way I heard of. You could delete the entries one by one. :D
 I guess setting all references to null is the easiest way to 'clear' an 
 AA.

(1) fill_values(aa); aa = null (2) fill_values(aa); aa.remove(...) For both methods time1/time2 is around 35/52, with aa size 10, 100, 1000, and 10000. Interesting enough, with aa size 1M, 10M, 100M time1/time2 is around 1/1. So (1) is prefered for 10-1000 elements situation i have, but it allocates memory each time :( while 2 reuses it, IMHO.
Nov 06 2011
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, November 06, 2011 04:11:07 Jonathan M Davis wrote:
 On Sunday, November 06, 2011 13:39:27 Alex_Dovhal wrote:
 "Marco Leise" <Marco.Leise gmx.de> wrote:
 No way I heard of. You could delete the entries one by one. :D
 I guess setting all references to null is the easiest way to 'clear'
 an
 AA.

Thanks. I tried both of them in small benchmark. Results are (1) fill_values(aa); aa = null (2) fill_values(aa); aa.remove(...) For both methods time1/time2 is around 35/52, with aa size 10, 100, 1000, and 10000. Interesting enough, with aa size 1M, 10M, 100M time1/time2 is around 1/1. So (1) is prefered for 10-1000 elements situation i have, but it allocates memory each time :( while 2 reuses it, IMHO.

2 doesn't necessarily reuse it. It depends on what the GC does and how AAs are currently implemented. It's likely that in both cases, you end up with a fair bit of stuff which is on the heap and no longer referenced such that if a garbage collection cycle runs, it would be collected (or if one doesn't run, it just sits there still taking up memory). The only real difference is that _some_ of the memory will be reused with 2, whereas with 1, you need a whole new AA. In both cases, new memory will be required. How much that is depends n the current implementation of AAs. And which one is more likely to trigger a GC cycle probably depends on a number of factors. So, it wouldn't suprise me at all either way. I imagine that it's at least simpler for the GC to collect the memory quickly in the first case, since the entire AA can be collected instead of all of it, but I don't know. AAs are a _completely_ different situation from dynamic arrays. With dynamic arrays, you have a clear block of contiguous memory that you're playing with, and it's obvious what's going to be reused if you want reuse. The situation is _far_ more complicated with a hash table, which is likely to have a fair number of items on the heap - particularly for handling each bucket (and there's a decent chance that each of those is a dynamic array). So, I very much doubt that your going to reuse much memory from an AA unless a GC cycle is run, regardless of whether you do #1 or #2.

And actually, I should point out that #2 would result in a _lot_ more overhead due to all the work done for each remove call than you get with #1. So, given that fact, I would actually _expect_ #1 to be faster in the general case. - Jonathan M Davis
Nov 06 2011
parent "Alex_Dovhal" <alex_dovhal yahoo.com> writes:
Thakns for details. Arfer another small benchmark, it appeared that addition 
to AA is 10x times slower than removal from it. So that's why (2) isn't so 
bad in my previous tests - most of time AA was adding elements to remove 
later. Anyway if (2) also reallocates it's much much worse that (1). 
Nov 06 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 06.11.2011, 00:15 Uhr, schrieb Alex_Dovhal <alex_dovhal yahoo.com>:

 "Marco Leise" <Marco.Leise gmx.de> wrote:
 Are you this Alex?

 As I understand it this function is defined in object_.d which is always
 imported by default and can be called on an (associative) array through  
 a
 mechanism called "universal function call", that matches the part before
 the dot with the first parameter of the function. This only works for
 arrays. So I believe it is a free function (to invalidate/finalize a
 variable) and not a property of an array at all.

Thanks for clarification. So now my question and task changes. Is there a way to reuse previous memory occupied by AA, when I need to change all of it element? E.g. for dynamic arrays it's possible to make: dyn_arr.length = 0; assumeSafeAppend(dyn_arr); fill_new_values(dyn_arr);

No way I heard of. You could delete the entries one by one. :D I guess setting all references to null is the easiest way to 'clear' an AA.
Nov 06 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, November 06, 2011 13:39:27 Alex_Dovhal wrote:
 "Marco Leise" <Marco.Leise gmx.de> wrote:
 No way I heard of. You could delete the entries one by one. :D
 I guess setting all references to null is the easiest way to 'clear' an
 AA.

Thanks. I tried both of them in small benchmark. Results are (1) fill_values(aa); aa = null (2) fill_values(aa); aa.remove(...) For both methods time1/time2 is around 35/52, with aa size 10, 100, 1000, and 10000. Interesting enough, with aa size 1M, 10M, 100M time1/time2 is around 1/1. So (1) is prefered for 10-1000 elements situation i have, but it allocates memory each time :( while 2 reuses it, IMHO.

2 doesn't necessarily reuse it. It depends on what the GC does and how AAs are currently implemented. It's likely that in both cases, you end up with a fair bit of stuff which is on the heap and no longer referenced such that if a garbage collection cycle runs, it would be collected (or if one doesn't run, it just sits there still taking up memory). The only real difference is that _some_ of the memory will be reused with 2, whereas with 1, you need a whole new AA. In both cases, new memory will be required. How much that is depends n the current implementation of AAs. And which one is more likely to trigger a GC cycle probably depends on a number of factors. So, it wouldn't suprise me at all either way. I imagine that it's at least simpler for the GC to collect the memory quickly in the first case, since the entire AA can be collected instead of all of it, but I don't know. AAs are a _completely_ different situation from dynamic arrays. With dynamic arrays, you have a clear block of contiguous memory that you're playing with, and it's obvious what's going to be reused if you want reuse. The situation is _far_ more complicated with a hash table, which is likely to have a fair number of items on the heap - particularly for handling each bucket (and there's a decent chance that each of those is a dynamic array). So, I very much doubt that your going to reuse much memory from an AA unless a GC cycle is run, regardless of whether you do #1 or #2. - Jonathan M Davis
Nov 06 2011