C vs. C++



  • und ich bleib trotzdem dabei.

    Ein gutes C++ Programm ist nicht langsamer als sein C-Kollege.
    Voraussetzung ist natuerlich ein gleichwertiger Compiler, was im embedded Bereich vermutlich nicht immer gegeben ist...



  • Ein gutes C++ Programm ist nicht langsamer als sein C-Kollege.

    Hab ich dass nicht so ähnlich geschrieben (für PCs)?

    Voraussetzung ist natuerlich ein gleichwertiger Compiler, was im embedded Bereich vermutlich nicht immer gegeben ist...

    Für sehr viele Controller steht gcc zur Verfügung. Das stellt also kein Problem dar.

    Also: C++ hat keine messbaren Nachteile (z.B. wegen virtual Funktionen o.ä.) bei PCs, Konsolen u.ä., aber bei Controllern mit 8Kb Rom, 2Kb Ram und 8Mhz (teilweise noch weniger) wirds eng im Vergleich zu C.



  • wusstest du, dass virtual Funktionen (also eigentlich die vtable) schneller sind als das vergleichbare switch (also eigentlich die Sprungtabelle)?



  • 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. ]



  • 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

    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:

    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).

    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:

    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

    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!

    Tip:
    Dies ist kein gutes C++-Programm:

    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.

    int quadrat(int i)
    {
      return i*i;//so einfach ist C++
    }
    

    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.

    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. ]



  • Original erstellt von volkard:
    **isses noch nicht, soweit ich feststellen kann.
    **

    Teste doch mal mit `std::cout.sync_with_stdio(false)' in der ersten Zeile. Meine Messungen mit der GCC-Reihe zeigte da Vorteile für `std::cout'.



  • 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.



  • Kann man nicht einen Thread wie "C vs. C++" in die FAQ aufnehmen?

    Dann kann man immer, wenn jemand sowas anfaengt auf die FAQ ver-
    weisen und erspart sich den Glaubenskrieg!

    mfg
    v R


Anmelden zum Antworten