DMD 0.161 release

xs0 xs0 at xs0.com
Thu Jun 22 04:02:32 PDT 2006


BenHinkle wrote:
>>> Consider this:
>>>
>>>   int can be implicitly converted to long.
>>>   Therefore, shouldn't int[] be usable as a long[]?
>>>
>>> It's an exactly analogous situation.
>> No, it isn't. int is of a different "class" than long, while an 
>> interface reference and a class reference point to exactly the same object.
>>
>> You also seem to miss the reduced complexity of implementation (a stated 
>> goal I believe). With a simple double lookup, interfaces can be handled 
>> in a single place, and I'd guess you could implement that very easily 
>> just by faking another calling convention.
> 
> Can you explain more what you mean by double lookup? I'm not aware of that
> technique.

It's very simple :)

 > iref.someFunction(...) // iref is an interface reference

becomes

 > iref.getVtbl(SomeInterface.classinfo)[2](iref, ...)

instead of the current

 > iref.someFunction(iref-offset, ...)


I tested speed of various calling methods with
http://www.xs0.com/d/ifaces.d.html

and here are the results I get:

               Normal:             12165450 / sec
    Through interface:             11764706 / sec
    Lookup every time:              9580379 / sec
     Optimized lookup:             13390466 / sec
     Static functions:             13224015 / sec

The number is function calls / second.

With a function of any significant complexity, the differences would be 
even smaller, and even here it's just around 20% in the worst case. And 
if a simple observation* is implemented in the optimizer, the speed loss 
in fact becomes speed gain (ok, in reality it would also be implemented 
for non-interface methods, so the speed would end up the same).

*) if the object reference doesn't change neither can the function pointer


>> On the other hand, if interface references point to a different address 
>> than class references, you need to store offsets somewhere, have to 
>> modify the address on every call, need to handle implicit conversions 
>> when passing function boundaries, etc. etc.
> 
> This technique I'm used to. It's called thunking and I believe it's the standard
> way of implementing MI and/or interfaces. That is, when a class implements an
> interface method it makes a thunk to adjust the 'this' pointer before calling
> the actual class method. So when you have an interface A and class C and call a
> method f in A that is implemented in C the slot in the vtable for f (which takes
> an A) calls the thunk to adjust the A to a C and then the thunk jumps to the
> method (which takes a C).

Well, I think there's a significant difference between MI and interfaces 
in that interfaces only allow methods, while with MI you also have 
fields to think of. Having to basically make a function call for each 
field access would indeed be too inefficient, but it's not the same case 
with methods, because the call itself usually takes only a (very) small 
part of total method execution time.


xs0



More information about the Digitalmars-d-announce mailing list