Use case: eliminate hidden allocations in buildPath

Manu turkeyman at gmail.com
Wed Dec 4 18:13:58 PST 2013


On 5 December 2013 11:02, Jonathan M Davis <jmdavisProg at gmx.com> wrote:

> On Wednesday, December 04, 2013 16:38:54 H. S. Teoh wrote:
> > What about a new overload that takes an output range instead of
> > returning a string?
>
> I would have thought that that would be the obvious way to solve the
> problem.
> In general, I think that when a function allocates any kind of string or
> array
> which it returns, we should overload it with a version that takes an output
> range. In many cases, it would probably even make sense to make the default
> just use std.array.appender and make it so that only the output range
> overload
> is really doing any work.
>

This seems the intuitive approach to me.


What to do in cases of allocation where we're not dealing with arrays being
> returned is a tougher question, and I think that that starts going into
> custom
> allocator territory, but for arrays, output ranges are definitely the way
> to go
> IMHO.
>

You mean for internal working buffers?
It get's tricky. In my experience, many functions can use alloca, with a
fallback in the event of very large workspaces.
In the event of very large workspaces, it is often possible to break the
process into stages which allow an iterative use of a smaller alloca-ed
buffer if the function doesn't perform highly random access on the working
data.
In the event of large workspace and heavily randomised access to the
working dataset (ie, difficult to avoid one large allocation), then and
only then, maybe start thinking about receiving an allocator to work with
(default arg to a gc allocator), or, if it's a large complex process, break
the process into sub-functions which the user can issue, and they will then
inherit ownership and management of the workspace, which they can treat how
they like.

These are some of my approaches. Almost all code I write must never
allocate, except for functions that produce new allocations, where either
receiving an output range or an allocator seems intuitive.

The most important question to ask is 'can this function possibly be called
recursively?'. Many library functions are effectively leaf functions, and
can't lead back into user code via any path, which means alloca is safe to
use liberally. If there is potential for a recursive call, then i guess you
need to start preferring receiving allocators or output ranges, unless the
alloca is in the order of a normal function's stack usage (<1kb-ish?).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20131205/d4bd3c03/attachment.html>


More information about the Digitalmars-d mailing list