Beweis: C ist schneller als C++ am Beispiel von std::vector



  • Also ich hab jetzt die große Schwachstelle entdeckt.

    1 Million mal

    std::vector<char> v;
    v.resize(4000);
    

    dauert bei mir ca. 11 Sekunden

    und 1 Million mal

    std::vector<char> v(4000);
    

    dauert ca. 77 Sekunden. 😮 😮

    Ich dachte immer das wäre komplett das selbe! Besteht da wirklich ein Unterschied? Wenn ja, welcher? Bitte lasst es mich verstehen. 🙂

    @TactX: An die Funktion hab ich nicht gedacht. 😉



  • Schau dir den einfach den Quellcode an...


  • Administrator

    Und wenn schon überhaupt, stimmt das doch gar nicht. So kann man das doch nicht vergleichen. Wenn schon müsste man es vom C-Beispiel ausgehend folgendermasen machen:

    // Die C-Variante
    for(int i = 0; i < 10000000; ++i)
    {
        char* pBuffer = malloc(4000);
        free(pBuffer);
    }
    
    // Die C++-Variante
    for(int i = 0; i < 10000000; ++i)
    {
        char* pBuffer = new char[4000];
        delete [] pBuffer;
    }
    

    Sonst hat das eine ja nichts mit dem anderen zu tun. Oder irre ich mich 😕

    Grüssli



  • toll.

    dummerweise hast du wohl verpennt, das es um Schnelligkeit garnicht mehr geht.
    Wenn du etwas verkaufst, und es halbwegs richtig programmiert ist, ist es schnell genug.
    Ob nun mit C das 10% schneller ist oder nicht interessiert keinen. Und wenn doch, verkaufst
    du dem Kunden halt eine schnellere Hardware, damit "optimierst" du dann dein Programm um einiges
    mehr, als es C jemals gekonnt hätte.
    Und wenn wir über Software reden, müssen wir auch über Wartungs und Entwicklungsaufwand reden,
    C kann keine OOP, keine Templates, bei komplexeren Problemstellungen wirst du also schnell einen
    erheblichen Mehraufwand haben.



  • @aufdecker:
    Aus irgendeinem Grund verwendet die resize Version memset und die ctor Version nicht. Guck dir den Source an wenn du magst, mich interessiert das jetzt nicht wirklich ausreichend mich da reinzukämpfen. Und dass memset schneller ist ist kein Wunder, da memset hoch optimiert ist, und nicht jedes Byte einzeln setzt, sondern mit speziellen Instruktionen mehrere (zumindest 16 denke ich) auf einmal.

    Sobald du die "intrinsic functions" einschaltest ist die memset Variante gleich langsam, da dann die optimierte Version von memset nicht verwendet wird sondern einfach "rep stosb".

    Im übrigen ist malloc+memset mit einem vector zu vergleichen doof, wenn dann müsstest du auf der C++ Seite schon "new char[]" und "uninitialized_fill_n" verwenden. Naja, whatevern.



  • Dravere schrieb:

    Und wenn schon überhaupt, stimmt das doch gar nicht. So kann man das doch nicht vergleichen. Wenn schon müsste man es vom C-Beispiel ausgehend folgendermasen machen:

    // Die C-Variante
    for(int i = 0; i < 10000000; ++i)
    {
        char* pBuffer = malloc(4000);
        free(pBuffer);
    }
    
    // Die C++-Variante
    for(int i = 0; i < 10000000; ++i)
    {
        char* pBuffer = new char[4000];
        delete [] pBuffer;
    }
    

    Sonst hat das eine ja nichts mit dem anderen zu tun. Oder irre ich mich 😕

    Grüssli

    Nein, finde ich auch. Ein Vergleich sollte eine bestimmte Aufgabe lösen und in der jeweiligen Sprache optimal gecoded, so wie im Zitat.
    C++ ist eine Erweiterung von C und kann logischerweise auch so benutzt werden.



  • ACHTUNG !!!! ACHTUNG !!!!

    Obwohl es die da oben nicht wahrhaben wollen und seit Jahren mit illegalen Machenschaften versuchen, die Wahrheit und den kleinen Mann zu unterdrücken, hier der Triumph der Freiheit: Der Beweis, dass Word langsamer ist als C.

    Anlegen von 40.000.000.000 (40 Mrd) Zeichen
    - in C (Programm mit malloc vom Aufdecker): 10 Sekunden
    - in Word (Eintippen mit Zeitmessung und Interpolation) : knapp 127 Jahre !!!

    Wie lange dauert es noch, bis die Politik reagiert und die Konsequenzen zieht ?
    Wann wird Bill Gates endlich der Gerechtigkeit des Volkes übergeben ?

    Wordnutzer aller Welt: Vereinigt Euch !!

    Gruß,

    Simon2.



  • Simon2 schrieb:

    ACHTUNG !!!! ACHTUNG !!!!

    Obwohl es die da oben nicht wahrhaben wollen und seit Jahren mit illegalen Machenschaften versuchen, die Wahrheit und den kleinen Mann zu unterdrücken, hier der Triumph der Freiheit: Der Beweis, dass Word langsamer ist als C.

    Anlegen von 40.000.000.000 (40 Mrd) Zeichen
    - in C (Programm mit malloc vom Aufdecker): 10 Sekunden
    - in Word (Eintippen mit Zeitmessung und Interpolation) : knapp 127 Jahre !!!

    Wie lange dauert es noch, bis die Politik reagiert und die Konsequenzen zieht ?
    Wann wird Bill Gates endlich der Gerechtigkeit des Volkes übergeben ?

    Wordnutzer aller Welt: Vereinigt Euch !!

    Gruß,

    Simon2.

    Idiot.



  • Kener schrieb:

    ...Idiot.

    Angenehm ! Simon2.

    Gruß,

    Simon2.



  • 😃 🤡 😃



  • wo soll hier der gag liegen? dass c einiges schneller sein kann als c++ ist doch wohl allen klar die oop verwenden. dafür ist das konzept stimmiger. hardware wird doch alle 18 monate doppelt so schnell. da kann man dann schon von assembler weg gehen und vielfach verschachtelte hochsprachen verwenden. 😉



  • marc--us schrieb:

    ...dass c einiges schneller sein kann als c++ ist doch wohl allen klar...

    Also mir nicht. Da oben werden (wie so oft) "Ä mit B" verglichen. vector<> macht einfach was Anderes als ein malloc/free-Paar. Wenn man nur das Letztere braucht, kann man in C++ new[]/delete[] verwenden unst ist plötzlich genauso schnell.

    Wenn ich new[]/delete[] mit einer gleichmächtigen selbstgeschriebene C-Vektor-Klasse vergleiche, wird mir plötzlich auffallen, dass "C++ viel schneller ist als C".....

    Gruß,

    Simon2.



  • marc--us schrieb:

    wo soll hier der gag liegen? dass c einiges schneller sein kann als c++ ist doch wohl allen klar die oop verwenden.

    Nö. Dir ist offensichtlich nicht klar, wie Compiler arbeiten.

    Ob du

    bar(&foo)
    

    oder

    foo.bar()
    

    schreibst, ist letztendlich egal. In der Theorie gibt es keinen wirklichen Grund, warum die eine oder andere Sprache langsamer oder schneller sein soll. Die Unterschiede zwischen C und C++ liegen nicht in der Geschwindigkeit, sondern in den angebotenen Sprachmitteln. Und messen kannst du sowieso nur Implementationen, die aber keine allgemeingültige Aussagekraft besitzen. Und wenn man schon Laufzeit messen will, dann sollte man auch Codeäquivalente benutzen. Hier ist ja noch nicht mal garantiert, dass der Allokator von std::vector und malloc/free identisch arbeiten.



  • Simon2 schrieb:

    marc--us schrieb:

    ...dass c einiges schneller sein kann als c++ ist doch wohl allen klar...

    Also mir nicht. Da oben werden (wie so oft) "Ä mit B" verglichen. vector<> macht einfach was Anderes als ein malloc/free-Paar. Wenn man nur das Letztere braucht, kann man in C++ new[]/delete[] verwenden unst ist plötzlich genauso schnell.

    Nein. Die vector-Variante macht im Prinzip das gleiche, wie die malloc/free-Variante. Darum habe ich auf meinem System auch praktisch identische Laufzeiten. Da braucht man auch nicht zu diskutieren, warum C++ langsamer ist, wenn es so nicht ist.

    Schaut doch einfach nochmal meinen Kommentar an. Dann denkt noch mal darüber nach. Ihr diskutiert, ob eine bestimmte Implementierung das eine oder andere besser optimieren kann. Gcc hat sicher nicht den weltbeste Optimierer aber aus den beiden Varianten macht er praktisch das selbe. Und wenn es nicht das selbe sein soll, dann frage ich mich, wie gcc darauf kommt, den selben Code auszuspucken.

    Tntnet



  • tntnet schrieb:

    ...Die vector-Variante macht im Prinzip das gleiche, wie die malloc/free-Variante....

    Von "der vector-Variante" habe ich gar nicht gesprochen, sondern von der Klasse std::vector, die einiges mehr/anders macht, als free()/malloc().
    Wenn jemand diese beiden gegeneinander vergleicht, mit dem Ziel, die "Performance einer Programmierspracce" zu untersuchen, bleibe ich dabei: "Ä&B".
    Dass eine bestimmte std::vector-Implementierung in einer bestimmten Methode auch free()/malloc() verwendet, mag sein, trifft aber auf Word auch zu und macht das Argument nicht stichhaltiger.

    Gruß,

    Simon2.



  • @Plotzenhotz: Ich konnte deine Antwort bis jetzt noch nicht ganz nachvollziehen. Ich bin mit dem Debugger beide Varianten durchgegangen und beide kommen in _Fill_n (Datei: xutility, Zeile: 2757) an wo eine for-Schleife genutzt wird.

    for (; 0 < _Count; --_Count, ++_First)
    	*_First = _Val;
    

    Von einem memset konnte ich nichts entdecken.
    Wo haste denn das gesehen? Oder optimiert der Compiler das im Release-Mode zu einem memset?



  • Ah es stimmt wirklich, ich habe jetzt im Release-Mode debugged, Disassembly und Symbolnamen eingeschaltet und dann hab ich das memset gesehen.
    Ich werde mal schauen ob ich noch den Grund herausfinden kann warum er die andere Variante nicht optimiert.

    Vielleicht hatte "Antwort" doch gar nicht so unrecht 😉



  • Übrigens: Beim MinGW Compiler (g++) ist es genau umgekehrt. Dort ist das mit dem Konstruktor schnell und mit resize lahm. 😃



  • Gleich unter der der "_Fill_n" Template Funktion gibts nen non-template-overload für "char*" der memset verwendet.
    Der Unterschied zwischen den beiden Funktionen ist dass der zu setzende Wert einmal als "const _Ty&" und einmal als "int" übergeben wird.

    Wenn du den Code genau durchguckst wirst du draufkommen dass es eigentlich keinen Grund für den Compiler gibt jemals den non-template-overload zu verwenden. Tut er aber aus irgendeinem Grund. Vielleicht ein Compiler Bug. Keine Ahnung...

    Und ja, er macht das auch nur in einem Release Build.

    Und nein, der VC 8 hat keinen "lahmen" Optimizer, eher einen der besten die es derzeit gibt (abgesehen von den Bugs 🙂 ).

    Der einzige Unterschied der mir ins Auge springt wäre dass in "_Insert_n" "_Val" kopiert wird, und diese Kopie ("_Tmp") dann an "_Ufill" weitergegeben wird anstatt "_Val" selbst. Da ich aber keinen overload von "_Ufill" gefunden hätte der nicht wieder eine const-ref für sein "_Val" Parameter erzwingt weiss ich trotzdem nicht wieso jemals der non-template-overload von "_Fill_n" verwendet werden sollte.



  • Und hier der Gegenbeweis, C ist langsamer als C++.

    Programmiersprache: C

    #include <string.h>
    #include <stdlib.h>
    
    int main()
    {
    	int i;
    
    	for(i = 0; i < 10000000; ++i)
    	{
    		char* pBuffer = malloc(4000);		
    		int j;
    		for(j=0;j<10000000;j++)memset(pBuffer, 0, 4000);
    		free(pBuffer);
    	}
    }
    

    Programmiersprache: C++

    #include <vector>
    
    int main()
    {
    	for(int i = 0; i < 10000000; ++i)
    	{
    		char* pBuffer = new char[4000];
    		memset(pBuffer, 0, 4000);
    		delete[] pBuffer;
    	}
    }
    

    Schon seltsam, gelle?


Anmelden zum Antworten