Hallo,
die Frage ist doch, wie Stroustrup die Aussage verstanden wissen will.
In einer perfekten Welt in der alle C++ Compiler toll optimieren und alle Bibliotheken gut geschrieben sind und in der es nur gute C++ Programmierer gibt, die nicht ständig irgendwo ausversehen temporäre Objekte erzeugen (und davon kann es in C++ ganz schnell ganz viele geben) und nicht völlig überflüssige Vererbung einsetzen und klobige Designs fabrizieren, hat C wahrscheinlich wirklich keine Vorteile gegenüber C++. Schließlich gibt es keinen sprachbedingten Performanceunterschied und C++ bietet zusätzlich viel reichhaltigere Sprackkonstrukte und vielmehr Möglichkeiten Fehler bereits zur Compilezeit zu entdecken.
Da die Welt aber nicht perfekt ist und da es schlechte C++ Compiler, schlechte C++ Bibliotheken und schlechte C++ Programmierer gibt und da es gleichzeitig sehr gute C Compiler, sehr gute C Bibliotheken und sehr gute C Programmierer gibt, existieren sicher auch Situationen/Projekte wo C eindeutig im Vorteil ist.
Man sollte sich nur mit beiden Sprachen sehr gut auskennen bevor man eine Entscheidung trifft. Die Sprachauswahl sollte schließlich keine Bauchauswahl sein. Auch wenn das einige hier im Forum anders sehen :)
[ Dieser Beitrag wurde am 07.08.2002 um 17:59 Uhr von HumeSikkins editiert. ]
_________________ Remember Sturgeon's Law:
"Ninety percent of everything is crap." and now go visit my Homepage ;-)
wusstest du, dass virtual Funktionen (also eigentlich die vtable) schneller sind als das vergleichbare switch (also eigentlich die Sprungtabelle)?
Jepp:
vtable bedeutet eine Zeigeroperationen (indizieren des this-Zeigers für die entsprechende Funktion der Klasse), bevor die Funktionsadresse bekannt ist.
switch ist einfach nur furchtbar langsam, du könntest auch if - else if ... schreiben. Bei n-cases gibts halt bis zu n Vergleiche wenn man Pech hat. switch sollte möglichst vermieden werden.
Original erstellt von Shade Of Mine:
wusstest du, dass virtual Funktionen (also eigentlich die vtable) schneller sind als das vergleichbare switch (also eigentlich die Sprungtabelle)?
Ist mir neu.
begründung:
switch ist dazu da, ne Sprongtabelle zu bauen!
Am nehme nur eben als Werte welche, die schön als Arrayindizes passen.
Also
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
enum {HUND,KATZE,MAUS,DELFIN};
...
switch(type)
{
case HUND: hund(this);break;
case KATZE: katze(this);break;
case MAUS: maus(this);break;
case DELFIN: delfin(this);break;
default: fehler();
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
enum {HUND,KATZE,MAUS,DELFIN};
...
switch(type)
{
case HUND: hund(this);break;
case KATZE: katze(this);break;
case MAUS: maus(this);break;
case DELFIN: delfin(this);break;
default: fehler();
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
enum {HUND,KATZE,MAUS,DELFIN};
...
switch(type)
{
case HUND: hund(this);break;
case KATZE: katze(this);break;
case MAUS: maus(this);break;
case DELFIN: delfin(this);break;
default: fehler();
}
so, hier haben wir erzeugt:
C/C++ Code:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
if(unsigned(typ)<=3)
jumpto tabelle[typ];
/*hier ist tab[0]*/hund();goto ende;
/*hier ist tab[1]*/katze();goto ende;
/*hier ist tab[2]*/maus();goto ende;
/*hier ist tab[3]*/delfin();goto ende;
else
fehler;
ende:
C/C++ Code:
1 2 3 4 5 6 7 8 9
if(unsigned(typ)<=3)
jumpto tabelle[typ];
/*hier ist tab[0]*/hund();goto ende;
/*hier ist tab[1]*/katze();goto ende;
/*hier ist tab[2]*/maus();goto ende;
/*hier ist tab[3]*/delfin();goto ende;
else
fehler;
ende:
C/C++ Code:
1 2 3 4 5 6 7 8 9
if(unsigned(typ)<=3)
jumpto tabelle[typ];
/*hier ist tab[0]*/hund();goto ende;
/*hier ist tab[1]*/katze();goto ende;
/*hier ist tab[2]*/maus();goto ende;
/*hier ist tab[3]*/delfin();goto ende;
else
fehler;
ende:
Und siehe da, es hat einen Vergleiche gekostet und einen Tabellezugriff.
Keine if-Orgie.
Auf manchen Compiler kann man den Vergleich noch weghauen (für mutige).
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11
enum {HUND,KATZE,MAUS,DELFIN};
...
assert(unsigned(typ)<=DELFIN);
switch(type)
{
case HUND: hund(this);break;
case KATZE: katze(this);break;
case MAUS: maus(this);break;
case DELFIN: delfin(this);break;
default: __assume(0);//code can not be reached
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11
enum {HUND,KATZE,MAUS,DELFIN};
...
assert(unsigned(typ)<=DELFIN);
switch(type)
{
case HUND: hund(this);break;
case KATZE: katze(this);break;
case MAUS: maus(this);break;
case DELFIN: delfin(this);break;
default: __assume(0);//code can not be reached
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11
enum {HUND,KATZE,MAUS,DELFIN};
...
assert(unsigned(typ)<=DELFIN);
switch(type)
{
case HUND: hund(this);break;
case KATZE: katze(this);break;
case MAUS: maus(this);break;
case DELFIN: delfin(this);break;
default: __assume(0);//code can not be reached
}
und er macht draus:
C/C++ Code:
jumpto tabelle[typ];
/*hier ist tab[0]*/hund();goto ende;
/*hier ist tab[1]*/katze();goto ende;
/*hier ist tab[2]*/maus();goto ende;
/*hier ist tab[3]*/delfin();goto ende;
ende:
C/C++ Code:
jumpto tabelle[typ];
/*hier ist tab[0]*/hund();goto ende;
/*hier ist tab[1]*/katze();goto ende;
/*hier ist tab[2]*/maus();goto ende;
/*hier ist tab[3]*/delfin();goto ende;
ende:
C/C++ Code:
jumpto tabelle[typ];
/*hier ist tab[0]*/hund();goto ende;
/*hier ist tab[1]*/katze();goto ende;
/*hier ist tab[2]*/maus();goto ende;
/*hier ist tab[3]*/delfin();goto ende;
ende:
Und jetzt kommt das Leckerli: hund(), katze(), maus() und delfin() können inline sein!
Und noch eins: Ich kann mit sizeof(typ) aussuchen, muß nicht immer ein Zeiger sein.
Und noch eins, ich kann mir aussuchen, wo im Objekt typ steht, evtl bei sowas wie
C/C++ Code:
struct Message
{
int timeToArrive;
int typ;
};
C/C++ Code:
struct Message
{
int timeToArrive;
int typ;
};
C/C++ Code:
struct Message
{
int timeToArrive;
int typ;
};
wo ich die Messages alle in nem heap halten will, kanns ja sein, daß der Zugriff aufs erste Member schneller ist.
Denn
int getTyp(Message* m)
wird zu
return *(int*)m;
statt
return *((int*)m+1);
Ist zwar nicht gerade bedeutend, aber ich halte es für falsch, zu sagen, vptrs seien einfach schneller als switch.
Original erstellt von Shade Of Mine:
Aber gerade bei kleinen Projekten denke ich, dass ich mehr Mehraufwand durch das Objekt Orientierte Design habe, als ich Nutzen daraus ziehe!
class Quadrat
{
private:
int i_;
public:
Quadrat(int i)
:i_(i)
{
}
void berechne()
{
i_*=i_;
}
int ergebnis()
{
return i_;
}
};
...
int x;
Quadrat q(x);
q.berechne();
x=q.ergebnis();
Man meide in C++ overengeneering.
C/C++ Code:
int quadrat(int i)
{
return i*i;//so einfach ist C++
}
C/C++ Code:
int quadrat(int i)
{
return i*i;//so einfach ist C++
}
C/C++ Code:
int quadrat(int i)
{
return i*i;//so einfach ist C++
}
Zitat:
OK, jetzt kommt sicher das gegenargument: man muss in C++ ja nicht Objekt Orientiert Programmieren. Stimmt! Aber dann sehe ich es eher als C denn als C++ an.
Es gibt mehr an C++ als virtuelle Funktionen. Und feine C-Programme sind meist auch objektorientiert.
Zitat:
Aber generell kann man sagen: C kann nichts was C++ nicht auch kann (logisch, denn C ist ja fast vollstaendig in C++ enthalten)
Ganz wichtiger Punkt. Das impliziert, daß man in C++ stets und jederzeit, sobald eine Lösung unter Verzicht von aufgeblasenen C++-Mitteln, also in C, schneller wäre, es machen kann, wie man es in C machen würde. Ist das nicht total Klasse?
Daher kann ich auch kaum nachvollziehen, wo C++ langsamer sein könnte.
Außer natürlich, weil die <iostream> so fett ist und ein dutzend von kilobytes Code macht. die wolllen geladen werden und fressen in der tat mehr ram als printf. aber naja, theoretisch kann cout schneller sein als printf, weil die typen bekannt sind und deshalb der formastring nicht geparsed werden muß. isses noch nicht, soweit ich feststellen kann.
[ Dieser Beitrag wurde am 07.08.2002 um 20:08 Uhr von volkard editiert. ]
Hier wurde der Speicheroverhead angesprochen. Um sowas zu vermeiden kann man Dinge wie einen pool verwenden. Aber malloc hat das selbe problem wie new und ist somit nicht C++-spezifisch.
_________________ Manual memory management is premature optimization.
Nächstes Thema anzeigen Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum nicht antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums
für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de
Werbekostenerstattung verdient werden kann.
Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de
enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt
(vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in
privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden.
Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere
übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.