On Tue, Apr 22, 2014 at 02:24:41PM -0400, Steven Schveighoffer via Digitalmars-d wrote: > On Tue, 22 Apr 2014 14:10:30 -0400, H. S. Teoh via Digitalmars-d > <[email protected]> wrote: > > >I'm going through some code and thinking of ways to reduce GC > >pressure, and came across a bit that needed to append some items to > >an array: > > > > T[] args; > > lex.expect("("); > > args ~= parseSingleItem(lex); > > while (!lex.empty) { > > lex.expect(","); > > args ~= parseSingleItem(lex); > > } > > lex.expect(")"); > > return computeResult(args); > > > >Now obviously, in the general case (with arbitrarily many number of > >items) some GC allocations will be needed, but the most common > >use-cases are actually only 1 or 2 items each time. Allocating lots > >of small arrays seem to be rather wasteful, so I thought to use a > >static array as a buffer instead. > > > >The question is, is there a way to take a slice of the static array, > >set the length to zero, and append to it with ~= such that when it > >runs out of space in the static buffer, it will reallocate a longer > >array on the GC heap? Or is this a bad idea? > > TL;DR: Yes, use Appender :) > > The reason appending even works is because of the metadata stored in > the heap. Obviously, stack frames and fixed-length arrays do not have > this data. > > When that metadata cannot be found, it reallocates because that's the > only option. > > However, Appender, initialized with a static buffer, knows the length > of its data, and stores its own capacity, separate from the heap. [...]
Unfortunately, the whole point of this exercise was to eliminate GC allocations for small arrays -- but since Appender's implementation allocates a private Data struct in its ctor, that kinda defeats the purpose. For the common case of 1 or 2 items only, it doesn't seem like Appender will perform any better, and it will introduce extra GC allocations to boot. :-( T -- What are you when you run out of Monet? Baroque.
