March 15, 2014
On 15 March 2014 10:49, Walter Bright <newshound2@digitalmars.com> wrote:

> On 3/14/2014 5:06 AM, Manu wrote:
>
>> In my experience, API layout is the sort of performance detail that
>> library
>> authors are much more likely to carefully consider and get right. It's
>> higher
>> level, easier to understand, and affects all architectures equally.
>> It's also something that they teach in uni. People write books about that
>> sort
>> of thing.
>> Not to say there aren't terrible API designs out there, but D doesn't make
>> terrible-api-design-by-default a feature.
>> Stuff like virtual is the sort of thing that only gets addressed when it
>> is
>> reported by a user that cares, and library authors are terribly reluctant
>> to
>> implement a breaking change because some user reported it. I know this
>> from
>> experience.
>> I can say with confidence, poor API design has caused me less problems
>> than
>> virtual in my career.
>>
>> Can you honestly tell me that you truly believe that library authors will
>> consider, as a matter of common sense, the implications of virtual (the
>> silent
>> default state) in their api?
>> Do you truly believe that I'm making a big deal out of nothing; that I
>> will
>> never actually, in practise, encounter trivial accessors and properties
>> that
>> can't inline appearing in my hot loops, or other related issues.
>>
>> Inline-ability is a very strong API level performance influence,
>> especially in a
>> language with properties.
>>
>> Most programmers are not low-level experts, they don't know how to protect
>> themselves from this sort of thing. Honestly, almost everyone will just
>> stick
>> with the default.
>>
>
>
> I find it incongruous to take the position that programmers know all about layout for performance and nothing about function indirection? It leads me to believe that these programmers never once tested their code for performance.
>

They probably didn't. Library authors often don't if it's not a library specifically intended for aggressive realtime use. Like most programmers, especially PC programmers, their opinion is often "that's the optimisers job".

That said, function inlining is perhaps the single most important API level
performance detail, and especially true in OO code (which advocates
accessors/properties).
Function calls scattered throughout your function serialise your code; they
inhibit the optimiser from pipelining properly in many cases, ie,
rescheduling across a function call is often dangerous, and compilers will
always take a conservative approach. Locals may need to be saved to the
stack across trivial function calls. I'm certain it will make a big
difference in many instances.

Compile some release code without -inline and see what the performance difference is, that is probably a fairly realistic measure of the penalty to expect in OO-heavy code.


I know what I'm doing, and even I, when I don't test things, always make
> some innocuous mistake that eviscerates performance. I find it very hard to believe that final-by-default will fix untested code.
>

I don't find it hard to believe at all, infact, I find it very likely that there will be a significant benefit to client code that the library author will probably have never given a moments thought to. It's usually considered fairly reasonable for programmers to trust the optimiser to at least do a decent job. virtual-by-default inhibits many of the most important optimisations; inlining, rescheduling, pipelining, and also increases pressure on the stack and caches.

And that's the whole thing here... I just don't see this as obscure or unlikely at all. If I did, I wouldn't care anywhere near as much as I do. All code has loops somewhere.


And the library APIs still are fixable. Consider:
>
>     class C {
>         void foo() { ... }
>     }
>
> and foo() needs to be final for performance, but we don't want to break
> existing users:
>
>     class C {
>         void foo() { foo2(); }
>         final void foo2() { ... }
>     }
>

The length you're willing to go to to resist a relatively minor breaking
change, with an unusually smooth migration path, that virtually everyone
agrees with is surprising to me.
Daniel Murphy revealed that it only affects 13% of classes in DMD's OO
heavy code. That is in line with my past predictions; most classes aren't
base classes, so most classes aren't actually affected.

I understand that you clearly don't believe in this change, and I grant
that is your prerogative, but I really don't get why... I just can't see it
when considering the balance.
Obviously I care about the compiler's codegen more than the average guy;
but as I see it, that's a compiler's primary purpose, and programmers are
supposed to be able to trust that it can and will do it well.


My questions above, they were serious questions. Please, I would really like to hear you answer those questions, or rephrase them if you like...

Can you honestly tell me that you truly believe that library authors will
consider, as a matter of common sense, the implications of virtual (the
silent default state) in their api?
Or you don't consider that to be something worth worrying about, ie, you
truly believe that I'm making a big deal out of nothing; that I will never
actually, in practise, encounter trivial accessors and properties that
can't inline appearing in my hot loops, or other related issues?


I won't post any more on the topic.


March 15, 2014
On Saturday, 15 March 2014 at 04:03:20 UTC, Manu wrote:
> That said, function inlining is perhaps the single most important API level
> performance detail, and especially true in OO code (which advocates
> accessors/properties).

OOP say ask, don't tell. Accessors, especially getters, are very anti OOP. The haskell of OOP would prevent you from returning anything from a function.
March 15, 2014
On Saturday, 15 March 2014 at 05:29:04 UTC, deadalnix wrote:
> On Saturday, 15 March 2014 at 04:03:20 UTC, Manu wrote:
>> That said, function inlining is perhaps the single most important API level
>> performance detail, and especially true in OO code (which advocates
>> accessors/properties).
>
> OOP say ask, don't tell. Accessors, especially getters, are very anti OOP. The haskell of OOP would prevent you from returning anything from a function.

Yeah, as I said, OO encourages bad design like no other paradigm...
March 15, 2014
On 3/14/2014 9:02 PM, Manu wrote:
> That said, function inlining is perhaps the single most important API level
> performance detail, and especially true in OO code (which advocates
> accessors/properties).

I find it peculiar to desire a 'final accessor'. After all,

    class C {
        int x;
        final int getX() { return x; } <= what the heck is this function for?
    }

The only reason to have an accessor function is so it can be virtual. If programmers are going to thoughtlessly follow rules like this, they might as well follow the rule:

    class C { final:


> Compile some release code without -inline and see what the performance
> difference is,

I'm well aware of the advantages of inline.


> The length you're willing to go to to resist a relatively minor breaking change,

It's a major breaking change. It'll break nearly every D program out there that uses classes.


> I understand that you clearly don't believe in this change, and I grant that is
> your prerogative, but I really don't get why... I just can't see it when
> considering the balance.

You may not agree with me, but understanding my position shouldn't be too hard. I've expounded at length on it.


> Can you honestly tell me that you truly believe that library authors will
> consider, as a matter of common sense, the implications of virtual (the silent
> default state) in their api?

I thought I was clear in that I believe it is a pipe dream to believe that code with nary a thought given to performance is going to be performant.

Besides, they don't have to consider anything or have any sense. Just blindly do this:

     class C { final:


> Or you don't consider that to be something worth worrying about, ie, you truly
> believe that I'm making a big deal out of nothing; that I will never actually,
> in practise, encounter trivial accessors and properties that can't inline
> appearing in my hot loops, or other related issues?

I think we're just going around in circles. I've discussed all this before, in this thread.

March 15, 2014
deadalnix píše v Pá 14. 03. 2014 v 22:25 +0000:
> On Friday, 14 March 2014 at 22:06:13 UTC, Daniel Kozák wrote:
> > First I think have something like
> >
> > @disable(final,nothrow) would be the best way, but than I think
> > about it
> > and realize that final(false) is much more better.
> >
> 
> If I may, final!false . We have a syntax for compile time parameter. Let's be consistent for once.
> 
> The concept is solid and is the way to go. DIP anyone ?

final!true
final!(true)
final(!true) oops :)



March 15, 2014
On Saturday, 15 March 2014 at 07:36:12 UTC, Walter Bright wrote:
> The only reason to have an accessor function is so it can be virtual.

No:

1. To have more readable code: using x, y, z, w to access an array vector
2. Encapsulation/interfacing to differing implementations.

Seems to me that the final by default transition can be automated by source translation.

Please don't send D further into the land if obscurity by adding !final...
At some point someone will create D--...

March 15, 2014
Am 15.03.2014 06:29, schrieb deadalnix:
> On Saturday, 15 March 2014 at 04:03:20 UTC, Manu wrote:
>> That said, function inlining is perhaps the single most important API
>> level
>> performance detail, and especially true in OO code (which advocates
>> accessors/properties).
>
> OOP say ask, don't tell. Accessors, especially getters, are very anti
> OOP. The haskell of OOP would prevent you from returning anything from a
> function.

What?!?

Looking at Smalltalk, SELF, CLOS and Eiffel I fail to see what you mean, given that they are the grand daddies of OOP and all have getters/properties.

--
Paulo
March 15, 2014
"Walter Bright"  wrote in message news:lg0vtc$2q94$1@digitalmars.com...

> I find it peculiar to desire a 'final accessor'. After all,
>
>      class C {
>          int x;
>          final int getX() { return x; } <= what the heck is this function for?
>      }

Yeah, it's stupid, but people do it all over the place anyway.

> It's a major breaking change. It'll break nearly every D program out there that uses classes.

This is nonsense.  I tried out the warning on some of my projects, and they required ZERO changes - because it's a warning!

Phobos requires 37 "virtual:"s to be added - or just change the makefile to use '-wi' instead of '-w'.  Druntime needed 25.

We don't even need to follow the usual 6-months per stage deprecation - We could leave it as a warning for 2 years if we wanted!

Grepping for class declarations and sticking in "virtual:" is as trivial as a fix can possibly be. 

March 15, 2014
On Saturday, 15 March 2014 at 07:36:12 UTC, Walter Bright wrote:
> On 3/14/2014 9:02 PM, Manu wrote:
>> That said, function inlining is perhaps the single most important API level
>> performance detail, and especially true in OO code (which advocates
>> accessors/properties).
>
> I find it peculiar to desire a 'final accessor'. After all,
>
>     class C {
>         int x;
>         final int getX() { return x; } <= what the heck is this function for?
>     }
>
> The only reason to have an accessor function is so it can be virtual.

Um... Read only attributes? Forgot the discussions about @property ?

This makes sense to me:
class C
{
    private int _x;

    ///Gets x
    final int x() @property { return x; }
}
March 15, 2014
Am 15.03.2014 08:36, schrieb Walter Bright:
> On 3/14/2014 9:02 PM, Manu wrote:
>> That said, function inlining is perhaps the single most important API
>> level
>> performance detail, and especially true in OO code (which advocates
>> accessors/properties).
>
> I find it peculiar to desire a 'final accessor'. After all,
>
>      class C {
>          int x;
>          final int getX() { return x; } <= what the heck is this
> function for?
>      }
>
> The only reason to have an accessor function is so it can be virtual.

I don't agree.

In any language with properties, accessors also allow for:

- lazy initialization

- changing the underlying data representation without requiring client code to be rewritten

- implement access optimizations if the data is too costly to keep around


--
Paulo