On 11 April 2013 09:23, Walter Bright <newshound2@digitalmars.com> wrote:
On 4/10/2013 4:00 AM, Manu wrote:
It doesn't have all sources. It could load a library. That can never be guaranteed.

Currently, a virtual call is done with:

   (*vtbl[i])(args...)

It makes me wonder if the following would be faster:

   method_fp = vtbl[i];
   if (method_fp == &method)
       method(args...)
   else
       (*method_fp)(args...)

Anyone care to dummy this up and run a benchmark?

**On a non-x86 machine.
It would depend how derived the class is, but I reckon there's good chance it would be slower. In the end, the work is the same, but you've introduced another hazard on top, a likely branch misprediction.
I think the common case with classes is that you're calling through a base-pointer, so virtual calls become more expensive, and the non-virtuals may save a cache miss, but gain a misprediction. I suspect the cache miss (a more costly hazard) would occur less often than the mispredicion, which, given a greater volume, might add up to be similar.
This is also very, very hard to profile realistically. Isolated test cases can't reveal the truth on this matter, and in the end, we remain in the same place, where non-virtual-by-default is clearly better.

It's also possible to, for the per-class static data, have a flag that says "isfinal", which is set to false at runtime whenever a new is done for a derived class. Then, the method test above becomes:

    if (isfinal)

Branch still exists, vcall is still required if you have a base pointer. Accessors might benefit, but incur the cost of a branch. Aside from virtual (or lack thereof), if() is possibly the second most dangerous keyword ;)
It's getting better with time though. Super-long pipeline architectures are slowly dying off.