October 31, 2014
On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
> 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?

Why a sink version instead of an Output Range?

October 31, 2014
On Friday, 31 October 2014 at 19:04:29 UTC, Walter Bright wrote:
> On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
>> 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?
>
> Why a sink version instead of an Output Range?

I guess because it's for druntime, and we don't want to pull in std.range?
October 31, 2014
On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote:
> On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
> >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?
> 
> Why a sink version instead of an Output Range?

To allow toString to be a virtual function, perhaps?

Besides, the sink version basically allows encapsulation of an output range -- instead of calling x.toString(outputRange) you just write:

	x.toString((const(char)[] data) { outputRange.put(data); });

Most of the time, you don't even need to bother with this, because given an output range, formattedWrite("%s"...) will automatically figure out which overload of toString to call and what arguments to pass to it.


T

-- 
The only difference between male factor and malefactor is just a little emptiness inside.
October 31, 2014
On Friday, 31 October 2014 at 11:42:05 UTC, Steven Schveighoffer wrote:
> On 10/31/14 4:40 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> On Thursday, 30 October 2014 at 20:15:36 UTC, Steven Schveighoffer wrote:
>>> I think the above result is deceptive, and the test isn't very useful.
>>> The RuntimeString toString isn't a very interesting data point -- it's
>>> simply a single string. Not many cases are like that. Most types have
>>> multiple members, and it's the need to *construct* a string from that
>>> data which is usually the issue.
>>>
>>> But I would caution, the whole point of my query was about data on the
>>> platforms of which Manu speaks. That is, platforms that have issues
>>> dealing with virtual calls. x86 doesn't seem to be one of them.
>>
>> OTOH, ArrayOfStrings shows that allocating is worse by several orders of
>> magnitudes. This will not change on any architecture. And the simple
>> sink variant is still faster than the rest by almost an order of
>> magnitude, this may also be unlikely to be much different on these
>> architectures.
>
> I find it hard to believe that the delegate version is going to be slower than the memory version on any architecture also. But I must defer to Manu as the expert in those architectures. This is why I asked for a test. The presented data is useful, but not for the purpose of my query. I need to know if it performs bad on these platforms, not how it performs on x86. We should be willing to entertain other proposals for how toString should work, but not if it's proven that what we have will suffice.
>
> It should be possible to perform such a test without D support.
>
> In any case, I think there is still room for improvement inside the implementations of toString as has been mentioned.
>
> -Steve
I wrote a Windows CE app to run on our printers here at HP to test what the Microsoft ARM compiler does with virtual function calls.  I had to do an operation with a global volatile variable to prevent the compiler from inlining the non-virtual function call but I finally got it to work.

Calling the function 100 million times yielded the following times:

Windows Compiler on ARM (Release)
-------------------------------------------
NonVirtual: 0.537000 seconds
Virtual   : 1.281000 seconds

Windows Compiler on x86 (Release)
-------------------------------------------
NonVirtual: 0.226000 seconds
Virtual   : 0.226000 seconds

Windows Compiler on x86 (Debug)
-------------------------------------------
NonVirtual: 2.940000 seconds
Virtual   : 3.204000 seconds


Here's the link to the code:

http://marler.info/virtualtest.c


October 31, 2014
On 10/31/2014 12:07 PM, H. S. Teoh via Digitalmars-d wrote:
> On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote:
>> On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
>>> 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?
>>
>> Why a sink version instead of an Output Range?
>
> To allow toString to be a virtual function, perhaps?

Output ranges can be virtual functions. All an output range is is a type with a "put" method.


> Besides, the sink version basically allows encapsulation of an output
> range

The point of an output range is to encapsulate and abstract. Putting another wrapper around it just gives the impression we don't know what we're doing.


> -- instead of calling x.toString(outputRange) you just write:
>
> 	x.toString((const(char)[] data) { outputRange.put(data); });
>
> Most of the time, you don't even need to bother with this, because given
> an output range, formattedWrite("%s"...) will automatically figure out
> which overload of toString to call and what arguments to pass to it.

What I object to with the sink design is there is no consistency in design - we cannot preach ranges as a best practice and then use some other methodology.

BTW, just to be clear, I applaud fixing druntime to remove unnecessary GC allocations, and agree that with proper design most of the allocations can go away. It's just that sink and output ranges are both designed to solve the same problem in pretty much the same way. The difference appears to be little more than tomayto tomahto.
October 31, 2014
On Fri, Oct 31, 2014 at 02:01:50PM -0700, Walter Bright via Digitalmars-d wrote:
> On 10/31/2014 12:07 PM, H. S. Teoh via Digitalmars-d wrote:
> >On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote:
> >>On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
> >>>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?
> >>
> >>Why a sink version instead of an Output Range?
> >
> >To allow toString to be a virtual function, perhaps?
> 
> Output ranges can be virtual functions. All an output range is is a type with a "put" method.

The problem is that you don't know the type of the output range in advance. So you'd have to templatize toString. Which means it can no longer be virtual.


T

-- 
Дерево держится корнями, а человек - друзьями.
October 31, 2014
On 10/31/14 2:11 PM, H. S. Teoh via Digitalmars-d wrote:
> On Fri, Oct 31, 2014 at 02:01:50PM -0700, Walter Bright via Digitalmars-d wrote:
>> On 10/31/2014 12:07 PM, H. S. Teoh via Digitalmars-d wrote:
>>> On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote:
>>>> On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
>>>>> 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?
>>>>
>>>> Why a sink version instead of an Output Range?
>>>
>>> To allow toString to be a virtual function, perhaps?
>>
>> Output ranges can be virtual functions. All an output range is is a
>> type with a "put" method.
>
> The problem is that you don't know the type of the output range in
> advance. So you'd have to templatize toString. Which means it can no
> longer be virtual.

Yah, for such stuff a delegate that takes a const(char)[] comes to mind. -- Andrei

October 31, 2014
On Friday, 31 October 2014 at 19:09:28 UTC, H. S. Teoh via Digitalmars-d wrote:
> Besides, the sink version basically allows encapsulation of an output
> range -- instead of calling x.toString(outputRange) you just write:
>
> 	x.toString((const(char)[] data) { outputRange.put(data); });

In recent compiler versions we can just write:

    x.toString(data => outputRange.put(data));
October 31, 2014
On Fri, Oct 31, 2014 at 02:57:58PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
> On 10/31/14 2:11 PM, H. S. Teoh via Digitalmars-d wrote:
> >On Fri, Oct 31, 2014 at 02:01:50PM -0700, Walter Bright via Digitalmars-d wrote:
> >>On 10/31/2014 12:07 PM, H. S. Teoh via Digitalmars-d wrote:
> >>>On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote:
> >>>>On 10/27/2014 12:42 AM, Benjamin Thaut wrote:
> >>>>>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?
> >>>>
> >>>>Why a sink version instead of an Output Range?
> >>>
> >>>To allow toString to be a virtual function, perhaps?
> >>
> >>Output ranges can be virtual functions. All an output range is is a type with a "put" method.
> >
> >The problem is that you don't know the type of the output range in advance. So you'd have to templatize toString. Which means it can no longer be virtual.
> 
> Yah, for such stuff a delegate that takes a const(char)[] comes to
> mind. --
[...]

Which is what the sink version of toString currently does.


T

-- 
Error: Keyboard not attached. Press F1 to continue. -- Yoon Ha Lee, CONLANG
November 01, 2014
On Friday, 31 October 2014 at 22:13:31 UTC, Jakob Ovrum wrote:
> On Friday, 31 October 2014 at 19:09:28 UTC, H. S. Teoh via Digitalmars-d wrote:
>> Besides, the sink version basically allows encapsulation of an output
>> range -- instead of calling x.toString(outputRange) you just write:
>>
>> 	x.toString((const(char)[] data) { outputRange.put(data); });
>
> In recent compiler versions we can just write:
>
>     x.toString(data => outputRange.put(data));

No need for the extra function, just call:

x.toString(&(outputRange.put));