Warum programmiert ihr in C?



  • Die erste Aussage ist misslungen, entschuldigt.

    std::sort schlagen, meinst du mit qsort? C hat eine kleinere Standardbibliothek als C++, deshalb verwende ich zusätzlich die GNU C Library, welche das mindestens so schnell kann (habs nicht gemessen).

    volkard schrieb:

    Cönner schrieb:

    // initialisiere this->native_thread_ptr________ mit einem nativen Thread Pointer der offiziellen Funktion des Betriebssystems
    if (this->native_thread_ptr________ == nullptr) // Jeder fähige C++-Programmierer hat irgendwo den templatigen nullptr-Trick liegen.
    { // neue Klammern gehören auf eine neue Zeile, alles andere ist Oracle Java-Style
      throw get_boost_from_this_boosty_library::i_can_t_create_the_thread_exception("Oh sorry, "
    "the Thread creation failed, so I have to throw the "
    "get_boost_from_this_boosty_library::i_can_t_create_the_thread_exception "
    "exception"); // hier liegt ein unhandlicher C-Style-String im Speicher, weil 
    // C++-Style-Strings noch mehr Overhead verursachen
    }
    

    Der Test ist in die Standard-Bibliothek ausgelagert, eine mündliche Abmachung zwischen dem Betriebssystementwickler und dem Ersteller der geschwindigkeitskritischen Anwendung ist verunmöglicht.

    Hä? Was soll das? Was wird da verunmöglicht?

    Wird nachher beschrieben. Die zentrale Aussage ist jedoch die folgende (Hauptsatz):
    Der Test, welche man in C mit dem Rückgabewert macht, wird in C++ von der Funktion ausgeführt. Es ist also keine Geschwindigkeitseinbusse, ein if zu verwenden. Und weglassen ist in C++ nicht möglich.

    volkard schrieb:

    Welches if(fail)?

    Mir fehlt ein typisches Beispiel für C++ exceptions.
    Aus dem Kopf ist mir keines eingefallen und in http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.2 schreiben die nur folgendes hin:

    void f10()
     {
       ...
       if (...some error condition...)
         throw some_exception();
       ...
     }
    

    Ich will nur sagen: if (...some error condition...) kann man in C bei Bedarf weglassen, in C++ ist es immer da.



  • Cönner schrieb:

    std::sort schlagen, meinst du mit qsort? C hat eine kleinere Standardbibliothek als C++, deshalb verwende ich zusätzlich die GNU C Library, welche das mindestens so schnell kann (habs nicht gemessen).

    Dann probier mal ein halbwegs generisches Sort in C zu schreiben. Es muss nicht so toll wie std::sort sein, aber wenigstens ein bisschen generisch sein, so dass ich nicht das komplette sort selber schreiben muss wenn ich etwas sortieren will.

    Der Test, welche man in C mit dem Rückgabewert macht, wird in C++ von der Funktion ausgeführt. Es ist also keine Geschwindigkeitseinbusse, ein if zu verwenden. Und weglassen ist in C++ nicht möglich.

    Das 1. if - ja. Aber du musst in C ja ueberall testen ob es erfolgreich war, da jede Funktion ja einen Fehler liefern kann. Du musst den Fehler ja per return durchreichen bis du ihn behandeln kannst. Das ist in C++ eben schneller, da du keine ifs hast und Compilermagie hier das erledigt.



  • Cönner schrieb:

    std::sort schlagen, meinst du mit qsort? C hat eine kleinere Standardbibliothek als C++, deshalb verwende ich zusätzlich die GNU C Library, welche das mindestens so schnell kann (habs nicht gemessen).

    Ist da ein qsort, das für jeden Vergleich eine Vergleichsfunktion aufrufen muß?
    Falls ja: Das müssen wir in C++ nicht. Schneller.
    Falls nein: Das muß wohl mal ausgemessen werden.
    [/quote]

    Cönner schrieb:

    Der Test, welche man in C mit dem Rückgabewert macht, wird in C++ von der Funktion ausgeführt. Es ist also keine Geschwindigkeitseinbusse, ein if zu verwenden.

    Klar. Die Funktionen zwischen hier un der main() brauchen das if aber nicht.

    Cönner schrieb:

    Und weglassen ist in C++ nicht möglich.

    Klar.
    Beispiel new(nothrow)

    Cönner schrieb:

    Ich will nur sagen: if (...some error condition...) kann man in C bei Bedarf weglassen, in C++ ist es immer da.

    Da bin ich mir nicht so sicher.



  • Shade Of Mine schrieb:

    Dann probier mal ein halbwegs generisches Sort in C zu schreiben.

    Hast du das nicht gesehen? `void *array' ist generisch.

    Shade Of Mine schrieb:

    Das 1. if - ja. Aber du musst in C ja ueberall testen ob es erfolgreich war, da jede Funktion ja einen Fehler liefern kann.

    Wenn ich sicher bin, dass in der einen Funktion kein Fehler auftritt, kann ich mir das if sparen, in C++ geht das nicht

    Meistens ist nur ein if vorhanden, das gibt schonmal den entscheidenden Geschwindigkeitsvorteil. Sobald mehrere if's vorhanden sind, benötigen C und C++ gleich lang (das letzt if wird gespart und beim Aufrufer hingeschrieben), ein weiterleiten der Fehler ist aber auch in C möglich.



  • volkard schrieb:

    Ist da ein qsort, das für jeden Vergleich eine Vergleichsfunktion aufrufen muß?
    Falls ja: Das müssen wir in C++ nicht. Schneller.
    Falls nein: Das muß wohl mal ausgemessen werden.

    volkard schrieb:

    Klar. Die Funktionen zwischen hier un der main() brauchen das if aber nicht.

    Weiterleiten ist in C++ schneller, das gestehe ich ein. Ich sehe nur nicht ein, wo das (in C) so häufig gebraucht wird, dass es ein Problem wäre

    volkard schrieb:

    Beispiel new(nothrow)

    In dem Fall schon (die hab ich vergessen), aber für jede Funktion eine nothrow-Überladung zu schreiben, bläht die Binary nur unnötig auf und ist so umständlich, dass das normalerweise beiseite geschoben wird.



  • Ups, das erste Zitat (Performanz von qsort) habe ich gar nicht beantwortet.
    Also ja, es muss jedesmal eine Funktion ausgeführt werden, die Sortierung ist aber `arbitrary' (für Standardtypen gibts natürlich ne andere).
    Und in C++ muss auch immer ein Funktionsobjekt aufgerufen werden (im Notfall kann es mit __force_inline ein ganz kleines bisschen schneller sein als mein qsort)

    Was bedeutet das

    volkard schrieb:

    Da bin ich mir nicht so sicher.



  • Spielst du auf ausnahmesicheren Code nach der Abfrage an?



  • Cönner schrieb:

    Was bedeutet das

    volkard schrieb:

    Da bin ich mir nicht so sicher.

    Das war ein Euphemismus für: Nein.



  • Cönner schrieb:

    volkard schrieb:

    Klar. Die Funktionen zwischen hier un der main() brauchen das if aber nicht.

    Weiterleiten ist in C++ schneller, das gestehe ich ein. Ich sehe nur nicht ein, wo das (in C) so häufig gebraucht wird, dass es ein Problem wäre

    Es muß immer weitergeleitet werden. Insofern ist es ein Problem.
    Aber auch die paar ifs kosten in der Praxis nicht gewaltig viel Zeit. C ist natürlich nicht *deutlich* langsamer. Ich werde nichts von einem Faktor 30 erzählen, wie andere hier.
    Aber es ist prinzipiell ein kleines kleines Bißchen langsamer. Nicht schneller.

    Das Sortieren kann ich gerade nicht ausmessen. Ich habe da was laufen, das bis morgen früh braucht. Wenn man böse zu C sein will, läßt man wohl am besten ein von rand() gefülltes int-Array nach dem letzten Byte sortieren.



  • OMG Volkard lass es einfach. 🙄 Auch du wirst hier niemanden mehr das missratene C++ schmackhaft machen. C++ ist genauso angenehm wie Durchfall. Es gibt unter den bekannten Progammiersprachen kaum einen größeren Schrott als C++. Wenn du irgendwann mit dem Studium fertig bist und vielleicht mal in der realen Welt ein Projekt abbekommst dann wähle bitte nicht C++ als erste Sprache.



  • Cönner schrieb:

    In dem Fall schon (die hab ich vergessen), aber für jede Funktion eine nothrow-Überladung zu schreiben, bläht die Binary nur unnötig auf und ist so umständlich, dass das normalerweise beiseite geschoben wird.

    Es ist aber auch sehr selten, daß man einen syscall nicht testen muß, ob er geklappt hat. Aber auch da bin ich mit meinen Klassen nicht verbohrt. Zum Beispiel bin ich so frech, niemals zu prüfen, ob ein CloseHandle funktioniert hat (das muß aber unser kleines Geheimnis bleiben, wenn Du das im C++-Forum ausplauderst, werde ich vielleicht gesteinigt).
    Das Aufblähen hier ist als ein space-time tradeoff zu betrachten. Das zero-cost exception handling übrigens auch. Für PCs empfehle ich es. Für embedded Kisten mit arg wenig Speicher natürlich nicht.



  • Ich fasse zusammen:

    Die, die gegen C++ trollen, haben die Sprache und ihre Konzepte nicht verstanden.
    Die, die sachliche Argumente für C++ bringen, haben beide Sprachen und deren Konzepte verstanden - ist ja bei C auch nicht so schwierig.



  • Is doch eh klar. Für jemanden der C++ und die Konzepte dahinter verstanden hat gibts keinen Grund gegen C++ zu trollen 😉



  • dot schrieb:

    Is doch eh klar. Für jemanden der C++ und die Konzepte dahinter verstanden hat gibts keinen Grund gegen C++ zu trollen 😉

    zum glück gibts ja keine guten c-coder (sonst würden sie ja dieses für sie zu anspruchsvolle c++ verstehen) 🤡



  • Also ich programmier in C#, zählt das auch?



  • Zusammenfassung schrieb:

    Ich fasse zusammen:

    Die, die gegen C++ trollen, haben die Sprache und ihre Konzepte nicht verstanden.
    Die, die sachliche Argumente für C++ bringen, haben beide Sprachen und deren Konzepte verstanden - ist ja bei C auch nicht so schwierig.

    Trifft den Nagel aufn Kopf



  • volkard schrieb:

    Ist da ein qsort, das für jeden Vergleich eine Vergleichsfunktion aufrufen muß?
    Falls ja: Das müssen wir in C++ nicht. Schneller.
    Falls nein: Das muß wohl mal ausgemessen werden.

    bool <T>::operator==(<T>) ist ja auch bestimmt keine Vergleichsfunktion.



  • Rudías schrieb:

    bool <T>::operator==(<T>) ist ja auch bestimmt keine Vergleichsfunktion.

    Natürlich war eine gemeint, die nicht inline ist.

    //C
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    
    #define SIZE (1024*1024*64)
    
    int comp(const void* a,const void* b){
    	return *(unsigned int*)a-*(unsigned int*)b;
    }
    
    int main(){
    	unsigned int* arr=malloc(SIZE*sizeof(unsigned int));
    	int i;
    	unsigned int hash=0;
    	clock_t start,end;
    	for(i=0;i<SIZE;i++)
    		arr[i]=rand();
    	start=clock();
    	qsort(arr,SIZE,sizeof(unsigned int),comp);
    	end=clock();
    	for(i=0;i<SIZE;i++){
    //		printf("%8x\n",arr[i]);
    		hash+=3*hash+arr[i];
    	}
    	printf("hash: %8x\n",hash);
    	printf("%f secs",(end-start)/(double)CLOCKS_PER_SEC);
    	return 0;
    }
    
    //C++
    #include <cstdlib>
    #include <cstdio>
    #include <ctime>
    #include <algorithm>
    using namespace std;
    
    #define SIZE (1024*1024*64)
    
    struct comp{
    	bool operator()(unsigned int const& a,unsigned int const& b){
    		return a<b;
    	}
    };
    
    int main(){
    	unsigned int* arr=(unsigned int*)malloc(SIZE*sizeof(unsigned int));
    	int i;
    	unsigned int hash=0;
    	clock_t start,end;
    	for(i=0;i<SIZE;i++)
    		arr[i]=rand();
    	start=clock();
    	sort(arr,arr+SIZE,comp());
    	end=clock();
    	for(i=0;i<SIZE;i++){
    //		printf("%8x\n",arr[i]);
    		hash+=3*hash+arr[i];
    	}
    	printf("hash: %8x\n",hash);
    	printf("%f secs",(end-start)/(double)CLOCKS_PER_SEC);
    	return 0;
    }
    
    //C++-func
    #include <cstdlib>
    #include <cstdio>
    #include <ctime>
    #include <algorithm>
    using namespace std;
    
    #define SIZE (1024*1024*64)
    
    /*struct comp{
    	bool operator()(unsigned int const& a,unsigned int const& b){
    		return a<b;
    	}
    };*/
    bool comp(unsigned int const& a,unsigned int const& b){
    	return a<b;
    }
    
    int main(){
    	unsigned int* arr=(unsigned int*)malloc(SIZE*sizeof(unsigned int));
    	int i;
    	unsigned int hash=0;
    	clock_t start,end;
    	for(i=0;i<SIZE;i++)
    		arr[i]=rand();
    	start=clock();
    	sort(arr,arr+SIZE,comp);
    	end=clock();
    	for(i=0;i<SIZE;i++){
    //		printf("%8x\n",arr[i]);
    		hash+=3*hash+arr[i];
    	}
    	printf("hash: %8x\n",hash);
    	printf("%f secs",(end-start)/(double)CLOCKS_PER_SEC);
    	return 0;
    }
    

    Zugegeben, der Test ist gemein und künstlich. Er soll nur den Effekt der Komparator-Klasse als Template-Argument darstellen.

    Bei mir kommt übrigens raus, aber nicht stabil, weil ich so viel Mist nebenher laufen habe.
    qsort: 19.8s
    std::sort mit Funktionszeiger: 16.8s
    std::sort mit Komparatorklasse: 8.6s



  • Cönner schrieb:

    std::sort schlagen, meinst du mit qsort?

    Nein, qsort hatte ich eigentlich als Kandidaten gar nicht in Erwägung gezogen wegen der Funktionsaufrufe. Ich meinte mit allen zur Verfügung stehenden Mitteln, solange Dein Verfahren auf Vergleichen basiert.

    std::sort ist normalerweise so schnell, daß ich es nicht schneller hinkriege (vergleichsbasierend). Ich will nicht ausschließen, daß Du es schaffst. Aber vermutlich brauchst Du schon ein paar Tage dafür, wenn nicht mehr. Aber dann würdest auch Du sagen, daß std::sort verflixt schnell ist.



  • @volkard

    okay also vergleichen wir jetzt eine sort funktion mit geinlineter vergleichsfunktion (was dann auch pro zu sortierendem datentyp eine eigene funktion erfordert) vs. normaler vergleichsfunktion 🙄

    derart ungleiche vergleiche sehe ich besonders gerne... evtl. erklärst uns nächstes mal den unterschied zwischen einem segelflieger und nem a380 😃


Anmelden zum Antworten