On Tuesday, 22 April 2014 at 18:47:16 UTC, Dmitry Olshansky wrote:
22-Apr-2014 22:10, H. S. Teoh via Digitalmars-d пишет:
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?
Should be a canonical use case for ScopeBuffer
https://github.com/D-Programming-Language/phobos/blob/master/std/internal/scopebuffer.d
Except that it has crippled usability e.g. you need to call
free manually.
I've been working on a "ScopedAppender" that is *bit* slower than
ScopeBuffer, but can be used on any generic types, and is
nothrow/ctfe/pure/"sometimes safe". I'm giving it the "finishing
touches".
But in the meantime, normal appender+clear can work:
int[50] buf;
auto app = appender(buf[]);
app.clear();
//app is ready for use.
The "issue" though is that appender itself as a reference type,
so just declaring it allocates, which kind of gets in the way of
setting up a local scratch space to begin with.