toString refactor in druntime

Manu via Digitalmars-d digitalmars-d at puremagic.com
Mon Oct 27 17:01:50 PDT 2014


 28 October 2014 04:40, Benjamin Thaut via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> Am 27.10.2014 11:07, schrieb Daniel Murphy:
>
>> "Benjamin Thaut"  wrote in message news:m2kt16$2566$1 at digitalmars.com...
>>>
>>> I'm planning on doing a pull request for druntime which rewrites every
>>> toString function within druntime to use the new sink signature. That
>>> way druntime would cause a lot less allocations which end up beeing
>>> garbage right away. Are there any objections against doing so? Any
>>> reasons why such a pull request would not get accepted?
>>
>>
>> How ugly is it going to be, since druntime can't use std.format?
>
>
> They wouldn't get any uglier than they already are, because the current
> toString functions within druntime also can't use std.format.
>
> An example would be to toString function of TypInfo_StaticArray:
>
> override string toString() const
> {
>         SizeStringBuff tmpBuff = void;
>         return value.toString() ~ "[" ~
> cast(string)len.sizeToTempString(tmpBuff) ~ "]";
> }
>
> Would be replaced by:
>
> override void toString(void delegate(const(char)[]) sink) const
> {
>         SizeStringBuff tmpBuff = void;
>         value.toString(sink);
>         sink("[");
>         sink(cast(string)len.sizeToTempString(tmpBuff));
>         sink("]");
> }

The thing that really worries me about this synk API is that your code
here produces (at least) 4 calls to a delegate. That's a lot of
indirect function calling, which can be a severe performance hazard on
some systems.
We're trading out garbage for low-level performance hazards, which may
imply a reduction in portability.
I wonder if the trade-off between flexibility and performance went a
little too far towards flexibility in this case. It's better, but I
don't think it hits the mark, and I'm not sure that hitting the mark
on both issues is impossible.

But in any case, I think all synk code like this should aim to call
the user supplied synk delegate at most *once* per toString.
I'd like to see code that used the stack to compose the string
locally, then feed it through to the supplied synk delegate in fewer
(or one) calls.

Ideally, I guess I'd prefer to see an overload which receives a slice
to write to instead and do away with the delegate call. Particularly
in druntime, where API and potential platform portability decisions
should be *super*conservative.

> The advantage would be that the new version now ideally never allocates.
> While the old version allocated 3 times of which 2 allocations end up beeing
> garbage right away.
>
> Also I rember reading that the long term goal is to convert all toString
> functions to the sink version.
>
> Kind Regards
> Benjamin Thaut


More information about the Digitalmars-d mailing list