www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Creating dynamic arrays of known size

reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
So, I'm plodding along with my AA implementation that *hopefully* will
eventually reach the point where it's usable enough to be dropped into
druntime. I'm writing .keys and .values right now, and wondering what's
the best way to construct the returned array.

Obviously, using =~ repeatedly is a bad idea, since we already know the
resulting array size. Would this be the best way to do it?

	Key[] keys;
	keys.length = num_keys;
	for (size_t i=0; i < num_keys; i++) {
		keys[i] = ...;
	}

Looking at aaA.d, I see that _aaKeys calls gc_malloc directly and sets
BlkAttr.NO_SCAN.  Should I just copy this code?


T

-- 
It's bad luck to be superstitious. -- YHL
Mar 08 2012
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Mar 09, 2012 at 03:10:21PM +0100, Andrej Mitrovic wrote:
 Isn't this just as good?
 
 Key[] keys;
 keys.reserve(num_keys)
 foreach (key; keys_in_aa)
    keys ~= key;
I suppose that should work. Although it does open up a new can of worms: reserve is system and also impure. I can see why, because it interacts with the GC, so by definition it affects state outside of itself. But if language-level constructs such as arrays use the GC, does that then make them impure? That doesn't seem like a good idea (can't use arrays in pure functions -- seems unnecessarily limiting). Alternatively, can reserve() be made pure? Since in a sense it "only affects the array". At the very least, can reserve be made trusted? Currently, all of this causes AA.keys and AA.values to be impure and system, which seems a bit extreme to me. (Again, comes back to the point of language-level constructs: AA.keys/.values can't be used in pure functions; seems unnecessarily limiting.) On Fri, Mar 09, 2012 at 09:39:16AM -0500, Steven Schveighoffer wrote:
 On Fri, 09 Mar 2012 01:59:34 -0500, Jonathan M Davis
 <jmdavisProg gmx.com> wrote:
[...]
I see two options. Allocate the entire array, set the length to 0,
and use assumeSafeAppend (or maybe the function that it uses, since
assumeSafeAppend is in _object.d) so that appending doesn't cause
reallocations, or create the array as mutable and then cast it to the
appropriate type.

1.

auto keys = new Key[](num_keys);
keys.length = 0;
assumeSafeAppend(keys);
for(i; 0 .. num_keys)
    keys ~= ...;

2.

auto keys = new (Unqual!Key)[](num_keys);
foreach(ref key; keys)
    key = ...;

auto actualKeys = cast(Key[])keys;
Use the second method. This is low-level runtime code, it should be as fast as possible. Casting is OK as long as it's justified.
[...] OK. T -- What doesn't kill me makes me stranger.
Mar 09 2012