www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Creating dynamic arrays of known size

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