Design Problem Virtuelle Funktionen ja oder nein?
-
Hallo,
ich habe ein Problem.
Bei uns soll eine Graphik sehr schnell gezeichnet werden.
Die Graphikprimitive können GDI, XWindow oder anderes sein.Die Performance ist sehr wichtig. Wir programmieren in C++
Jetzt frage ich mich, ob es eine gute Idee ist, das Design mit Vererbung und virtuellen Funtionen zu lösen.
Also ungefähr folgendermaßen:class Painter
{
public:
virtual void drawLine(...) = 0;
etc.
};classs GDIPainter
{
public:
virtual void drawLine(...) {....};
etc.};
Virtuelle Funktionen haben den Nachteil, daß sie Laufzeit kosten.
Jetzt gibt es bei uns Leute, die meinen, es gäbe Compiler, die das so optimieren können, daß eine Laufzeitverschlechterung nicht zu erwarten sei?Hat damit jemnad schon Erfahrung gesammelt?
Hat jemand eine andere Idee, wie man so ein Designproblem lösen könnte?Danke und Gruß, Urs
-
Natürlich kostet virtual. Allerdings sollte das bei heutigen Rechnern verschmerzbar sein. Selbst Anwendungen die schnelle 3D Grafiken rendern und ausgeben (z.B. Computerspiele) nutzen z.T. solch ein Klassendesign.
Allerdings solltest du GDIPainter auch von Painter ableiten. Sonst is das ganze ja witzlos!

grüße
-
Oh man, machen sich die Leute heute immer noch wegen der vtable sorgen? vtable ist auf einem x86 nur 32bit groß, d.h. da wird ein einziger jump mehr ausgeführt, als wenn es keine virtuelle Funktion ist. OK, wenn man 1 Mio. Objekte zeichnen will, macht das mit ner vtable 1 Mio. Sprünge zus. aus. Wenn ein moderner Prozessor pro Jump 1 Taktzyklus braucht, verschwende ich 1 MHz. Weiß nicht ob das bei den heutigen CPUs ins Gewicht fällt.
Eines geht nur: optimale Performance um jeden Preis (in dem Fall kein OO-Design) oder lieber OO-Design?Wenn man wirklich Performance haben muß, kann man alternativ nur mit Templates arbeiten. Also so wie es die STL macht. Aber da muß man sich dann wirklich nochmal hinsetzen und sich ein Design ausdenken.
So in etwa:
class circle{ void draw(); }; class line{ void draw(); }; template<T> draw(T &shape) { shape.draw(); } void foo() { cirlce c; draw(c); line l; draw(l); }Ist ja das STL-Konzept, das man nicht-virtuelle Klassen hat und die Algorithmen global sind.
-
Artchi schrieb:
Oh man, machen sich die Leute heute immer noch wegen der vtable sorgen? vtable ist auf einem x86 nur 32bit groß, d.h. da wird ein einziger jump mehr ausgeführt, als wenn es keine virtuelle Funktion ist. OK, wenn man 1 Mio. Objekte zeichnen will, macht das mit ner vtable 1 Mio. Sprünge zus. aus. Wenn ein moderner Prozessor pro Jump 1 Taktzyklus braucht, verschwende ich 1 MHz.
In deiner Argumentation ist ja einiges schief. Erstmal zum unwesentlichen: die vtable ist 32bit PRO EINTRAG groß. Und es wird auch kein zusätzlicher Jump ausgeführt (nichtmal ein zusätzlicher Call), sondern die Adresse des Calls wird vorher durch zwei Speicherzugriffe ermittelt. Jetzt zum wesentlichen: Das entscheidende bei virtuellen Funktionen ist, dass ein virtueller Funktionsaufruf nicht geinlinet werden kann, weil der Compiler in der Regel nicht weiß, welchen dynamischen Typ das vorliegende Objekt hat.
Weiß nicht ob das bei den heutigen CPUs ins Gewicht fällt.
Eines geht nur:
optimale Performance um jeden Preis (in dem Fall kein OO-Design) oder lieber OO-Design?Ah die OO-ist-langsam-Leier
Ich übergebe an der Stelle an volkard
Aber guck dir mal das Design der iostream-Library an, dort wurde die dynamische Natur eines Streams, also die Abhängigkeit von der physischen Datenquelle, auf hoher Ebene von der statischen Natur, der Eigenschaft des Streams als Zeichenstrom, entkoppelt. OO ist das trotzdem.
-
Den Zugriff auf eine virtuelle Funktion als zeitkritisch einzustufen...
*Kopf schüttel*Auf der anderen Seite habe ich dieses Gerücht auch schon bei uns in der Firma gehört...
Meistens braucht man sich über solche Optimierungen keine Gedanken machen, weil an anderen Stellen im Verhältnis dazu viel mehr Zeit verbraucht wird.
Möchte man ein Programm auf Zeit optimieren macht man dies nicht in dem man kleine Zeitverluste wegoptimiert.
Ein Schleifendurchlauf, das Kopieren eines Objekts, ... ist in der Hinsicht wesentlich teurer.Außerdem sollte man bedenken, dass das Umschiffen von virtuellen Funktionen ganz leicht mehr Zeit kosten kann als man dadurch einspart....
-
Bei solchen Argumenten frage ich mich immer, warum programmiert ihr in C++? Der bei weitem wichtigste Vorteil von C++ gegenüber anderen Sprachen ist der hohe Grad an Kontrolle über überflüssige Dinge, die zur Laufzeit stattfinden oder nicht (mit dem natürlich auch Verantwortung einhergeht, die mehr Gehirnschmalz == Entwicklungsaufwand erfordert). Wenn einem die Verantwortung zuviel ist und man auf die Kontrolle freiwillig verzichtet, wozu dann C++ und nicht Lisp oder Ruby oder Java?
-
weil man in c++ kann, aber nicht muss.
-
Hallo,
danke für die Beiträge.
Die Variante mit dem STL-Konzept interessiert mich.
Artchi wo kann ich da mehr drüber lesen?Vielen Dank, Urs
-
Hi Urs
Stichwort: Metaprogrammierung
http://www.mitp.de/imperia/md/content/vmi/29842/1.pdf
http://www.cdc.informatik.tu-darmstadt.de/lehre/SS05/seminar/C++/Hoffmann_Meta.pdf
http://erdani.org/