digitalmars.D - Creating dynamic arrays of known size
- H. S. Teoh (16/16) Mar 08 2012 So, I'm plodding along with my AA implementation that *hopefully* will
- H. S. Teoh (21/53) Mar 09 2012 I suppose that should work.
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
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:[...][...] OK. T -- What doesn't kill me makes me stranger.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.
Mar 09 2012