Garbage collection, and practical strategies to avoid allocation

Jonathan M Davis jmdavisProg at gmx.com
Fri May 31 21:16:30 PDT 2013


On Saturday, June 01, 2013 04:47:39 Brad Anderson wrote:
> I played around with adding an overload that accepted an output
> range to some of the std.string functions identified in my run of
> -vgc over phobos[1] (after Jonathan pointed out this is probably
> the best approach and is already what formattedWrite does).  It
> worked fine but it did make me realize there aren't a lot of
> output ranges available to plug in at the moment (appender and
> lockingTextWriter are the only two that come to mind though there
> may be others).  Appender isn't useful if your goal is to avoid
> the GC.  Array!char et al aren't output ranges (whether they
> should be or not I have no idea).  static arrays would need some
> sort of wrapper to make them output ranges I believe unless it
> was decided that put() should work by replacing the front and
> calling popFront for them (which I kind of doubt is the desired
> behavior).
> 
> (feel free to correct me on any of this, range experts)
> 
> 1. http://goo.gl/HP78r

Dynamic arrays are output ranges. The one potential hitch there though relates 
to the fact that they get written to rather than appended to. This is actually 
exactly what you want in a situation like Manu's. However, that means that you 
have to worry about an output range running out of space and how you deal with 
that.

If it's know how much will need to be appended, presumably you can check 
length if hasLength!R is true. Otherwise, I guess that the right thing to do 
is to check empty (arrays get shrunk as they're written to, so they'll be 
empty when you can't call put on them anymore). Unfortunately, put doesn't 
seem to worry about the case where the ouput range is full/empty, so the 
result when calling put on an empty range is undefined. The situation is even 
worse with narrow strings (assuming that put works with them - I'm not sure 
that it does at the moment) given that even if you knew their length (which 
you wouldn't if you were going by hasLength), you wouldn't know whether a put 
would succeed when the string was nearly empty, as the actual number of 
elements that the dchar would take up would depend on its value.

In general, I don't think that output ranges have really been sorted out on 
quite the level that input ranges have been, and I think that some discussion 
is in order with regards to how to handle things like when the range can't be 
put into anymore. Given that one reason to use output ranges is for 
performance-critical code that doesn't want to allocate, throwing when the 
range is empty is probably a bad idea, and it's unclear that we can reasonably 
determine in the general case whether you can put to an output range before 
you actually try it. One solution to that would be to make bool return whether 
it succeeded or not, but it's an issue that definitely needs to be explored a 
bit.

So, I very much think that the correct thing is to use output ranges, but how 
to use them needs to be better defined, and we probably need to better sort out 
some of their details (like the finish function which the hash stuff uses).

- Jonathan M Davis


More information about the Digitalmars-d mailing list