June 01, 2013
On 05/31/2013 10:27 PM, Jonathan M Davis wrote:
> On Saturday, June 01, 2013 09:04:50 Manu wrote:
>> **applause**
>> Someone other than me said it, out loud!
>> This is a magnificent day! :)
> 
> Well, the discussions at dconf convinced me. Certainly, at this point, I think that the only semi-viable excuse for not making functions non-virtual by default is the code breakage that it would cause, and given how surprisingly minimal that is, I think that it's definitely worth it - especially when the kind of folks whose code Walter is most worried about breaking are the guys most interested in the change.
> 
> - Jonathan M Davis
> 


Making everything final by default would IMO kind of break
automated mock classes generation for unit testing,
automatic proxy class generation for DB entities, and
other OOP niceities.

And it wasn't just marking methods final which got the
D version of the raytracer in this thread faster than
the C++ version in the end. (it was a combination of
four or five things, which involved a bit of unrolling,
avoiding array literals, and so on).

--jm


June 01, 2013
On Friday, May 31, 2013 23:59:45 Juan Manuel Cabo wrote:
> Making everything final by default would IMO kind of break
> automated mock classes generation for unit testing,
> automatic proxy class generation for DB entities, and
> other OOP niceities.

Then just mark them all as virtual if you don't want to have to worry about it.

> And it wasn't just marking methods final which got the
> D version of the raytracer in this thread faster than
> the C++ version in the end. (it was a combination of
> four or five things, which involved a bit of unrolling,
> avoiding array literals, and so on).

Far more than just a raytracer cares about whether functions are virtual, and no, making member functions non-virtual by default will not suddenly speed up code everywhere, but there _is_ a cost to having member functions virtual by default, and there's almost no benefit to it IMHO. And it seems to be folks who use D in real programs in real companies who most want functions to be non- virtual by default. Both Don and Manu are completely on board with making member functions non-virtual by default and hate the fact that they're not.

- Jonathan M Davis
June 01, 2013
On Friday, 31 May 2013 at 19:17:05 UTC, Sean Cavanaugh wrote:
> On 5/31/2013 4:42 AM, Manu wrote:
>>
>> People already have to type 'override' in every derived class, and
>> they're happy to do that. Requiring to type 'virtual' in the base is
>> hardly an inconvenience by contrast. Actually, it's quite orthogonal.
>> D tends to prefer being explicit. Why bend the rules in this case,
>> especially considering the counterpart (override) is expected to be
>> explicit? Surely both being explicit is what people would expect?
>>
>
> Maybe the solution is to make everyone equally unhappy:
>
> all (non constructor) class methods must be either final, override, or virtual, if you leave one of these off, you get an error :)

A method can be override AND final.
June 01, 2013
On Saturday, 1 June 2013 at 02:58:59 UTC, Juan Manuel Cabo wrote:
>> Well, the discussions at dconf convinced me. Certainly, at this point, I think that the only semi-viable excuse for not making functions non-virtual by default is the code breakage that it would cause, and given how surprisingly minimal that is, I think that it's definitely worth it - especially when the kind of folks whose code Walter is most worried about breaking are the guys most interested in the change.
>> 
>> - Jonathan M Davis
>> 
>
> Making everything final by default would IMO kind of break
> automated mock classes generation for unit testing,
> automatic proxy class generation for DB entities, and
> other OOP niceities.
>

Yeah, everybody seems to ignore that. OOP is slow in general, due to excess of indirections, so if its loose its benefits . . .
June 01, 2013
Am 01.06.2013 05:08, schrieb Jonathan M Davis:
> On Friday, May 31, 2013 23:59:45 Juan Manuel Cabo wrote:
>> Making everything final by default would IMO kind of break
>> automated mock classes generation for unit testing,
>> automatic proxy class generation for DB entities, and
>> other OOP niceities.
>
> Then just mark them all as virtual if you don't want to have to worry about
> it.
>
>> And it wasn't just marking methods final which got the
>> D version of the raytracer in this thread faster than
>> the C++ version in the end. (it was a combination of
>> four or five things, which involved a bit of unrolling,
>> avoiding array literals, and so on).
>
> Far more than just a raytracer cares about whether functions are virtual, and
> no, making member functions non-virtual by default will not suddenly speed up
> code everywhere, but there _is_ a cost to having member functions virtual by
> default, and there's almost no benefit to it IMHO. And it seems to be folks who
> use D in real programs in real companies who most want functions to be non-
> virtual by default. Both Don and Manu are completely on board with making
> member functions non-virtual by default and hate the fact that they're not.
>
> - Jonathan M Davis
>

In OO languages where methods are virtual by default, writing mock classes is usually a matter of extending and overriding said classes.

In languages with final by default, one is forced to use Assembly or bytecode rewriting tools to be able to override those classes behaviour.

In .NET  case the Moles/Pex frameworks from Microsoft research were so loved by developers that Microsoft made it part of .NET 4.5 under the name  Fake framework.

The same for the C++ with frameworks like Isolator++.

Of course with virtual by default it is also possible to make a method
or class as final, thus causing the same issues with mocking as final by
default does.

Just my .02€ input to the discussion.

--
Paulo




June 01, 2013
I actually don't feel final by default is a big deal at all. Of all the factors that caused the poor performance that was discussed in the original post, final is the least significant one, only caused 5% to %7 of a speed penalty in a heavily recursive and looping program. Because of this I think its effect in less demanding scenario is negligible. Those who really needs the extra speed can simply add final to their methods in the hot path.

On Saturday, 1 June 2013 at 06:35:38 UTC, Paulo Pinto wrote:
> In OO languages where methods are virtual by default, writing mock classes is usually a matter of extending and overriding said classes.
>
> In languages with final by default, one is forced to use Assembly or bytecode rewriting tools to be able to override those classes behaviour.
>
> In .NET  case the Moles/Pex frameworks from Microsoft research were so loved by developers that Microsoft made it part of .NET 4.5 under the name  Fake framework.
>
> The same for the C++ with frameworks like Isolator++.
>
> Of course with virtual by default it is also possible to make a method
> or class as final, thus causing the same issues with mocking as final by
> default does.
>
> Just my .02€ input to the discussion.
>
> --
> Paulo

June 01, 2013
finalpatch:

> I actually don't feel final by default is a big deal at all. Of all the factors that caused the poor performance that was discussed in the original post, final is the least significant one, only caused 5% to %7 of a speed penalty in a heavily recursive and looping program. Because of this I think its effect in less demanding scenario is negligible. Those who really needs the extra speed can simply add final to their methods in the hot path.

So profiling matters not just for people that write D code, but also for compiler implementers that should focus on the things that most impact the performance.

Is the escape analysis for dynamic arrays already in Bugzilla as enhancement request? How much work does it need to be implemented? And how much gain is it going to give to D programs performance?

Bye,
bearophile
June 01, 2013
On Friday, 31 May 2013 at 15:02:00 UTC, bearophile wrote:
> Thanks to Kenji the latest dmd 2.063 solves part of this problem:
> http://d.puremagic.com/issues/show_bug.cgi?id=2356
>
> Maybe this improvement is not yet in LDC/GDC.

Regarding static array initialization from literals, yes, that change isn't in 2.062.

However, what pains me a bit is that LDC does even manage to remove the dynamic array allocation after the fact:

---
__D9raytracer4Vec36__ctorMFxfZS9raytracer4Vec3:
	movss	DWORD PTR [RSP - 12], XMM0
	movss	DWORD PTR [RSP - 8], XMM0
	movss	DWORD PTR [RSP - 4], XMM0
	mov	EAX, DWORD PTR [RSP - 4]
	mov	DWORD PTR [RDI + 8], EAX
	mov	RAX, QWORD PTR [RSP - 12]
	mov	QWORD PTR [RDI], RAX
	mov	RAX, RDI
	ret
---

It just happens too late in the optimizer pipeline for the temporary memcpy to go away. Re-running the IR through the LLVM optimizer then produces this:

---
__D9raytracer4Vec36__ctorMFxfZS9raytracer4Vec3:
	movss	DWORD PTR [RDI], XMM0
	movss	DWORD PTR [RDI + 4], XMM0
	movss	DWORD PTR [RDI + 8], XMM0
	mov	RAX, RDI
	ret
---

 — David
June 01, 2013
On Friday, 31 May 2013 at 06:41:19 UTC, Manu wrote:
> It would be nice
> if array operations would unroll for short arrays. Particularly so for
> static arrays!

It definitely is something we need to implement. There is just no excuse not to, and it hampers the practicality of a nice language feature. I didn't profile the original program yet, but I bet it's one of the major reasons why the LDC version is so slow.

I wonder where the best place to do this would be though. Doing it in the frontend would allow all three compilers to take advantage of the transformation, but it's really glue code stuff.

IIRC, GDC already does something like that?

David
June 01, 2013
On 6/1/13 2:54 AM, finalpatch wrote:
> I actually don't feel final by default is a big deal at all. Of all the
> factors that caused the poor performance that was discussed in the
> original post, final is the least significant one, only caused 5% to %7
> of a speed penalty in a heavily recursive and looping program. Because
> of this I think its effect in less demanding scenario is negligible.
> Those who really needs the extra speed can simply add final to their
> methods in the hot path.

Would be great to collect a summary of the changes and their benefits.

Thanks finalpatch and everyone else for this work.


Andrei