April 16, 2004 Re: Efficient interfaces (was Re: No Size of type bug in D!) | ||||
---|---|---|---|---|
| ||||
Posted in reply to christopher diggins | christopher diggins schrieb:
> I think you got off track somewhere. The issue is that interfaces
> implemented as ABC's are inherently less efficient (because of the wrognful
> and unnecessary virtualization of functions) than when implemented
> alternatively such as demonstrated by the HeronFront project at
> http://www.heron-language.com/heronfront.html .
But then again, class A inherits from an interface I, which declares a() and b(). Class B inherits from a class A and implements the interface. Class B overrides an implementation of one of the functions a() from an interface I, but leaves b() untouched.
If the b() calls a() in B, the class behaves uncoherently. This is not uncommon in C++, so in D principal decision was met to make everything virtual in classes.
There are a few technical solutions to that - either such calls have to be dispatched virtually, or they can be made direct, but then each function has to be generated anew for each descendant class even if it was not overriden. These 2 make sense in different situations. The first is good for development, and for large modular systems which makes it "linkable". The second was implemented in Sather compiler, and is good for whole-program compilation - it allows to use agressive strategies to eiminate all unused code as well as agressive inlining. D can princpally support both startegies - and when the popularity of D reaches a certain point, i'm sure agressive whole-program compilers will appear. Currently, it's non-agressive C++-like only, and that for a reason. Nontheless, even in such cases D can principally cut it better than C++.
-eye
|
April 16, 2004 Re: Interface code snippet: (Improved version) | ||||
---|---|---|---|---|
| ||||
Posted in reply to christopher diggins | "christopher diggins" <cdiggins@users.sourceforge.net> wrote in message news:c5nk6s$1ljs$1@digitaldaemon.com... > Hi Walter, > > Here is a sample implementation of a struct FuBar implementing an interface > InterfaceFuBar which contains two functions: void Fu() and void Bar(), I'll > let you do your own poking and prodding at the example and I welcome any feedback on the code itself as I am somewhat rusty at C++. Let me know if you require commenting of the code etc. So I improved on the version by removing the requirement of inheritance required on the implementing class. Just to reiterate what the heck is going on here, this is an example high performance implementation of interfaces (as they are defined in the Java specification anyway, see: http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface ) #include<iostream> using namespace std; int naff = 0; struct IFuBar { // member struct for typecasting object struct DUMMY_IFuBar { void Fu() { }; void Bar() { }; }; // ITable type for this interface template<typename SELF> struct ITABLE_IFuBar { void(SELF::*Fu)(); void(SELF::*Bar)(); }; // member struct for typecasting ITable struct DUMMY_ITABLE_IFuBar : public ITABLE_IFuBar<DUMMY_IFuBar> { // empty }; // member fields DUMMY_IFuBar* mpObject; DUMMY_ITABLE_IFuBar* mpTable; // member functions // default ctor IFuBar() { Assign(NULL, NULL); } // assignment ctor template<typename T> IFuBar(T& o) { Assign(&o, GetStaticITable<T>()); } // copy ctor template<> IFuBar(IFuBar& i) { Assign(i.mpObject, i.mpTable); } // assignment from an arbitrary object that implements the interface functiosn template<typename T> IFuBar& operator=(T& o) { Assign(&o, GetStaticITable<T>()); return *this; } // copy assignment template<> IFuBar& operator=(IFuBar& o) { Assign(o.mpObject, o.mpTable); return *this; } // assignment implementation void Assign(void* pObject, void* pTable) { mpObject = (DUMMY_IFuBar*)pObject; mpTable = (DUMMY_ITABLE_IFuBar*)pTable;; } // create static ITable for given object type template<typename T> ITABLE_IFuBar<T>* GetStaticITable() { static ITABLE_IFuBar<T> itable = { T::Fu, T::Bar }; return &itable; } // interface functions void Fu() { (mpObject->*(mpTable->Fu))(); } void Bar() { (mpObject->*(mpTable->Bar))(); } }; struct FuBar { void Fu() { naff = 0; }; void Bar() { naff = 1; }; }; struct BarFu { void Fu() { naff = 2; }; void Bar() { naff = 3; }; }; int main() { FuBar f; BarFu b; IFuBar x; x = f; x.Fu(); cout << naff << endl; x.Bar(); cout << naff << endl; IFuBar y = b; x = y; // this line is crucial, it demonstrate that IFuBar does not need the type of the object to work x.Fu(); cout << naff << endl; x.Bar(); cout << naff << endl; cin.get(); return 0; } |
April 18, 2004 Re: Interface code snippet: (Improved version) | ||||
---|---|---|---|---|
| ||||
Posted in reply to christopher diggins | It is still using pointers to functions, so I don't see where the speed up is. BTW, D implements interface dispatch much more efficiently than Java does (it's two machine instructions), so is it possible you are comparing the speedup of Heron with Java? |
April 19, 2004 Re: Interface code snippet: (Improved version) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:c5uvgd$d6j$1@digitaldaemon.com... > It is still using pointers to functions, so I don't see where the speed up is. BTW, D implements interface dispatch much more efficiently than Java does (it's two machine instructions), so is it possible you are comparing the speedup of Heron with Java? I apologize, I am doing a bad job of explaining myself. I will try again. HeronFront generates interface reference objects (in C++) which are compatable with any object that implements the set of function signatures that make up the interface. This is done without requiring the object to do anything special (like making its functions virtual). So the speed up is within the objects referenced by HeronFront interface objects, compared with objects who inherit from an ABC and make all its functions virtual. There is no significant speedup between the dynamic dispatch mechanisms themselves. I have a small page and some sample code at http://www.heron-language.com/cpp-iop-example.html . Am I making more sense? -- Christopher Diggins http://www.cdiggins.com http://www.heron-language.com |
April 25, 2004 Re: Interface code snippet: (Improved version) | ||||
---|---|---|---|---|
| ||||
Posted in reply to christopher diggins | "christopher diggins" <cdiggins@users.sourceforge.net> wrote in message news:c6175v$1821$1@digitaldaemon.com... > "Walter" <walter@digitalmars.com> wrote in message news:c5uvgd$d6j$1@digitaldaemon.com... > > It is still using pointers to functions, so I don't see where the speed up > > is. BTW, D implements interface dispatch much more efficiently than Java does (it's two machine instructions), so is it possible you are comparing > > the speedup of Heron with Java? > > I apologize, I am doing a bad job of explaining myself. I will try again. > > HeronFront generates interface reference objects (in C++) which are compatable with any object that implements the set of function signatures that make up the interface. This is done without requiring the object to do > anything special (like making its functions virtual). So the speed up is within the objects referenced by HeronFront interface objects, compared with > objects who inherit from an ABC and make all its functions virtual. There is > no significant speedup between the dynamic dispatch mechanisms themselves. I > have a small page and some sample code at http://www.heron-language.com/cpp-iop-example.html . > > Am I making more sense? ok, thanks for the reference. |
Copyright © 1999-2021 by the D Language Foundation