Späte Bindung ohne virtuelle Funktionen
-
Hallo,
ich habe eine Designproblem.
Bei uns soll eine Graphik erzeugt werden, bei der sehr viele Graphikprimitive aufgerufen werden.
Die Zeichenprimitiven soll austauschbar sein, d.h. man soll zwischen GDI, XY, ZZ wählen dürfen.Die 1. Variante das Design mit einer gemeinsamen abstrakten Basisklasse mit virtuellen Funktionen zu machen, kostet leider sehr viel Laufzeit, als wenn ich direkt die Zeichenprimitiven aufrufe ohne virtuelle Funktionen. Ich habe Vergleichsmessungen gemacht. Laufzeit ist für uns sehr wichtig.
Mittlerweile bin ich bei folgenden Design:
class CGDI
{
public:
void Line(...){..}};
class CXY
{
public:
void Line(...){..}};
template<T> Line(T &t)
{
t.Line();
}void func()
{
CGDI a;
Line(a);
CXY b;
Line(b);
}Ich will aber dahin kommen:
void func()
{
CMyClass a;
a.Line(..)
}Der Client soll sich nicht darum kümmern müssen, welche Graphikausgabe benutzt wird.
Ich zerbrech mir schon die ganze Zeit den Kopf, vlt. hat habt Ihr noch Ideen?Danke für Hilfe,
Urs
-
hola
falls ich dich nicht falsch verstanden habe, kannst es auch so machen:
class CGDI { public: void Line(...){..} }; class CXY { public: void Line(...){..} }; template <class T> void func(void) { T gdi_obj; gdi_obj.Line(..); // oder so: T().Line(..); }ob virtuelle funktionen die grafikausgabe wirklich so verlangsamen moechte ich mal leicht bezweifeln. alleine die WinGDI ist bei zeichenoperationen schon mal recht langsam, das eine virtuelle funktionen wahrscheinlich kaum spuerbar sein wird.
wenn du z.b. viele 7-ecke, 3D-balken o.ae. zeichnest, solltest du dafuer eigene funktionen bzw. klassen schreiben. da hast du dann nur noch einen virtuellen aufruf anstatt z.b. 10.
hast du schon mal nachgemesen um wieviel sich die grafische ausgabe verlangsamt, wenn du virtuelle funktionen aufrufst ?
Meep Meep
PS: bitte verwende Code-Tags und formatiere deinen Code etwas besser mit einrueckung
-
Also grundsätzlich... late binding kannst du über virtual functions, funtion pointer oder member function pointer machen. Eine Eingeschränkte Form lässt sich noch mittels if-/switch-Orgien machen - was aber so-gut-wie-immer noch langsamer ist als virtual functions. Wenn man keine garstig komplizierten Hierarchien hat (viel multiple inheritance und virtual inheritance) ist virtual ziemlich flott - solle auf einem Niveau mit (member) function pointern liegen. Wenn man sowas hat und virtual auf Grund von diversen Thunks zu langsam wird kann man immer noch auf function pointer zurückgreifen.
-
Hallo,
danke für Eure Beiträge.Also nach meinen Messungen sind die Aurufe mit virtuellen Methoden langsamer, als ohne virtuelle Methoden. Wir haben eine selbstgestrickte Library, die die Zeichenprimitive ausführt. Ich habe das Release gemessen. Benutzt wird der Microsoft Compiler C++ .NET.
Ich habe dann über Funktionszeiger gearbeitet.
Wir haben jetzt aber ein paar neue Leute, die darauf bestehen, das das Design umgestrickt wird auf virtuelle Methoden.
Deshalb bin ich am überlegen welche Alternativen es noch gibt ...Ich muß eben auch zur Laufzeit zwischen verschiedenen Graphikausgaben hin und her wechseln können.
Gruß, Urs
-
ich glaube wirklich nicht dass das problem in den virtuellen methoden liegt. die sind schon sehr effizient implementiert.
du kannst aber versuche die anzahl der aufrufe von virtuellen methoden zu verringern indem du groessere klassen baust.
aber rein interesse halber: wieviele virtuelle aufrufe hast du denn pro sekunde?
-
Wir haben ca. 30000 bis 50000 Zeichenaufrufe pro Bild.
Das wären dann 30000 bis 50000 virtuelle Funktionsaufrufe. Wie gesagt nach meinen Messungen wirkt sich das gravierend auf die Laufzeit aus!
-
EinGast schrieb:
Wir haben ca. 30000 bis 50000 Zeichenaufrufe pro Bild.
Das wären dann 30000 bis 50000 virtuelle Funktionsaufrufe. Wie gesagt nach meinen Messungen wirkt sich das gravierend auf die Laufzeit aus!
das sind dann ca 100.000Takte=100.000Hz=1MHZ. Schon allein bei nem 1GHZ rechner sind das nur 0,1% rechnerzeit. Meinst du, dass sich das so stark bei dir auswirkt?
Vorallem: bei 50000 Zeichenaufrufen pro Bild...kann es dann net sein, dass einige dieser Zeichenergebnisse überhaupt nicht mehr sichtbar sind? könnte man da nicht ein wenig power einsparen?
-
EinGast schrieb:
Ich muß eben auch zur Laufzeit zwischen verschiedenen Graphikausgaben hin und her wechseln können.
dann kannste ja die eine DLL rauswerfen und die andere DLL laden.
-
Oder vielleicht die 30.000 Aufrufe/Bild zu 1000 Batches oder so zusammenfassen, und bloss pro Batch eine (virtuelle) Funktion aufrufen. Falls das möglich ist.
30.000 kommt mir jetzt aber auch nicht sehr viel vor...