Warum programmiert ihr in C?



  • It0101 schrieb:

    Das sagt uns wiederum, dass es vom Compiler abhängig ist...

    Natuerlich ist es vom Compiler abhaengig.
    Und daher kommt auch der Mythos dass C schneller sei. Denn C Compiler sind so viel einfacher zu implementieren als C++ Compiler. Somit bleibt mehr Zeit den Optimizer zu verbessern.

    Der Vorteil von C ist die Einfachheit der Tools - Compiler, IDE, Debugger,... ist alles mit C einfacher als wenn man auch C++ bedenken muss.



  • Shade Of Mine schrieb:

    It0101 schrieb:

    Das sagt uns wiederum, dass es vom Compiler abhängig ist...

    Natuerlich ist es vom Compiler abhaengig.
    Und daher kommt auch der Mythos dass C schneller sei. Denn C Compiler sind so viel einfacher zu implementieren als C++ Compiler. Somit bleibt mehr Zeit den Optimizer zu verbessern.

    Gibts da heute noch nen merklichen Unterschied? Dass Compiler aus Prästandardzeiten nicht gut optimieren, sollte nicht verwundern, hat aber nichts mit modernen Compilern zu tun.



  • Michael E. schrieb:

    Gibts da heute noch nen merklichen Unterschied? Dass Compiler aus Prästandardzeiten nicht gut optimieren, sollte nicht verwundern, hat aber nichts mit modernen Compilern zu tun.

    Am Desktop nicht wirklich, da alle Compiler ja C und C++ koennen und somit ja den selben Optimizer verwenden.

    Wo es aber relevant ist, ist der Embedded Bereich.



  • Michael E. schrieb:

    It0101 schrieb:

    Das sagt uns wiederum, dass es vom Compiler abhängig ist...

    Meiner ist von 1998. Ich werds nachher doch mal mit gcc bauen...

    LOL, bist du mim VC6 angetreten? Wahrscheinlich noch im Debug-Mode 🤡

    Sehr lustig.. türlich nich... 😃

    Mir stellt sich eher die Frage, wie die std::string::find funktion implementiert ist, dass sie bei dir schneller ist als die C-Lösung die ja nun wirklich fast optimal ist. Dass es bei mir sicherlich an einer veralteten Implementierung der STL liegt erscheint mir logisch...



  • It0101 schrieb:

    Mir stellt sich eher die Frage, wie die std::string::find funktion implementiert ist, dass sie bei dir schneller ist als die C-Lösung die ja nun wirklich fast optimal ist

    Man glaubt es kaum, aber an der Standardbibliothekimplementierung haben viele Leute, die die Interna des Compilers und systemabhängige Tricks deutlich besser kennen als wir, viel Zeit investiert, um die Implementierungen schneller zu bekommen, als wir es in zwei Minuten hinbekommen.



  • Michael E. schrieb:

    It0101 schrieb:

    Mir stellt sich eher die Frage, wie die std::string::find funktion implementiert ist, dass sie bei dir schneller ist als die C-Lösung die ja nun wirklich fast optimal ist

    Man glaubt es kaum, aber an der Standardbibliothekimplementierung haben viele Leute, die die Interna des Compilers und systemabhängige Tricks deutlich besser kennen als wir, viel Zeit investiert, um die Implementierungen schneller zu bekommen, als wir es in zwei Minuten hinbekommen.

    Ich komme nicht umhin, dir zuzustimmen 😃
    Ist halt doch was anderes, als wenn man mal schnell was zusammenfriemelt ^^

    mein aktueller gcc bestätigt deine Zeitmessung auch noch... die Drecksau! 😃



  • Das sind also die C-Entwickler, die ja so viel Ahnung von den Details haben. 😃 😃



  • CodeBlocks mit mingw sagt jetzt wiederum, dass die C-Lösung schneller is... In ungefähr dem gleichen Prozentsatz wie der VC6...

    optimiert mit -O3 ...

    Der Compiler sollte relativ modern sein...

    Wer hat denn nun eigentlich recht? 😃



  • It0101 schrieb:

    CodeBlocks mit mingw sagt jetzt wiederum, dass die C-Lösung schneller is... In ungefähr dem gleichen Prozentsatz wie der VC6...

    optimiert mit -O3 ...

    Der Compiler sollte relativ modern sein...

    Wer hat denn nun eigentlich recht? 😃

    Welche Mingw Version? Hast du das uralt Mingw 3.6.5? Dann kein wunder, dass ist ja fast genauso alt wie VC6 *hust* große Unschärfe.

    Wie gesagt im Allgemeine und deswegen auch immer jeden Anfänger erzählt nehme die Sachen aus der STL, wenn du C++ Programmieren willst. Mikrooptimierung lohnen sich nicht. Erstens weil man viel Zeit investierten muss, welches mit einen relativen kleinen Leistungszuwachs belohnt wird. Zweitens die Komplexität einen Anfänger überfordert. Wenn du Experte bist, dann kannst du machen, wie du es für richtig hältst, aber dann wirst du in Regeln dein Code auch nicht hier mit Probleme posten 😛



  • Dies ist Compiler abhängig, verstehst du das immer noch nicht!?
    Und in der STL ist sowiso das Zeitkritische in Assembler geschrieben.



  • lowbyte_ schrieb:

    Dies ist Compiler abhängig, verstehst du das immer noch nicht!?
    Und in der STL ist sowiso das Zeitkritische in Assembler geschrieben.

    Schwachsinn.



  • lowbyte_ schrieb:

    Dies ist Compiler abhängig, verstehst du das immer noch nicht!?
    Und in der STL ist sowiso das Zeitkritische in Assembler geschrieben.

    Ich versteh das schon. Was ich aber nicht erwarte ist, dass die Unterschiede derart enorm sind... Kleinere Unterschiede hätte ich erwartet aber nicht derart extreme...

    Ist die STL nun eigentlich teilweise in ASM geschrieben oder nicht?
    Das wäre ja zumindest ein plausibler Grund.



  • @It0101
    @MichaelE

    Die Funktion von It0101 ist auch tatsächlich erheblich schneller als std::string::find(), wenn man sie richtig - und zwar als C-Code -
    aber nicht als C++ - Code unter Visual Studio 2010 kompiliert (dort kann man das wahlweise einstellen).
    Dann schaltet man natürlich auch noch die C++ - Ausnahmen ebenso bei den Compiler-Optionen ab, weil wir verwenden ja kein C++.
    Ansonsten jeweils ein herkömmlicher Release-Build (mit den Standardvorgaben bei den Projekteinstellungen).
    Und schon konnte man It0101's FindC in der gleichen Zeit doppelt so oft aufrufen wie std::string::find() (das ohne die C++ - Ausnahmen gar nicht erst kompilierbar war).
    Was den C++ Code hauptsächlich so träge macht, ist die Runtime, die jederzeit vom DAU (C++ 'Programmierer') ausgehen muss und für jedes Unvermögen eine eingebaute Ausnahmebehandlung bereitzustellen hat (Wie es der 'Standard' eben so vorsieht).
    Als C - Programmierer habe ich die Freiheit, von einer Funktion anzunehmen, dass sie einwandfrei funktioniert (bzw. weiß man im Voraus, dass die Anwender der Funktion keinen Schabernack damit treiben werden), dadurch spart man sich den Ausnahmen-Wildwuchs und Rückgabewerte-Prüfzwang auch ein und schöpft das volle Highspeed-Potential von C damit auch aus. Als C++ Programmierer kann man sich das nicht frei aussuchen und d'rum brauchts den Overhead mit den Exceptions.



  • Causlacher schrieb:

    lowbyte_ schrieb:
    Und in der STL ist sowiso das Zeitkritische in Assembler geschrieben.

    Schwachsinn.

    Beweise mir dass dies Schwachsinn ist !



  • STL bedeutet Standard Template Library.

    Und bei mir:
    C -> 674 ms
    C++ -> 396 ms

    Aufruf: g++ main.cpp -O3

    das ohne die C++ - Ausnahmen gar nicht erst kompilierbar war

    Ich kann -fno-rtti -fno-exceptions (musste den boost-Kram rausschmeissen) angeben und compilieren. Hatte aber keine Auswirkungen.



  • Es ist möglich, dass einzelne Spezialisierungen in Assembler geschrieben sind. Glaub ich aber nicht, bevor ich es sehe.



  • Ausnahmeerscheinung schrieb:

    @It0101
    @MichaelE

    Die Funktion von It0101 ist auch tatsächlich erheblich schneller als std::string::find(), wenn man sie richtig - und zwar als C-Code -
    aber nicht als C++ - Code unter Visual Studio 2010 kompiliert (dort kann man das wahlweise einstellen).
    Dann schaltet man natürlich auch noch die C++ - Ausnahmen ebenso bei den Compiler-Optionen ab, weil wir verwenden ja kein C++.
    Ansonsten jeweils ein herkömmlicher Release-Build (mit den Standardvorgaben bei den Projekteinstellungen).
    Und schon konnte man It0101's FindC in der gleichen Zeit doppelt so oft aufrufen wie std::string::find() (das ohne die C++ - Ausnahmen gar nicht erst kompilierbar war).
    Was den C++ Code hauptsächlich so träge macht, ist die Runtime, die jederzeit vom DAU (C++ 'Programmierer') ausgehen muss und für jedes Unvermögen eine eingebaute Ausnahmebehandlung bereitzustellen hat (Wie es der 'Standard' eben so vorsieht).
    Als C - Programmierer habe ich die Freiheit, von einer Funktion anzunehmen, dass sie einwandfrei funktioniert (bzw. weiß man im Voraus, dass die Anwender der Funktion keinen Schabernack damit treiben werden), dadurch spart man sich den Ausnahmen-Wildwuchs und Rückgabewerte-Prüfzwang auch ein und schöpft das volle Highspeed-Potential von C damit auch aus. Als C++ Programmierer kann man sich das nicht frei aussuchen und d'rum brauchts den Overhead mit den Exceptions.

    Hast du das so gemessen, dass ich das nachvollziehen kann?



  • Hier mal die Implementation bei MinGW für "find"

    template<typename _CharT>
        const typename char_traits<_CharT>::char_type*
        char_traits<_CharT>::
        find(const char_type* __s, std::size_t __n, const char_type& __a)
        {
          for (std::size_t __i = 0; __i < __n; ++__i)
            if (eq(__s[__i], __a))
              return __s + __i;
          return 0;
        }
    

    An dem Code kann es also nicht liegen. Ganz offensichtlich kochen die auch nur mit Wasser.

    Ich hab jetzt mal mehrere Messungen mit verschiedenen Anwendungsgebieten und verschiedenen Compilern gemacht und festgestellt, dass die Ergebnisse stark schwanken. Mal ist das C schneller und mal ist das STL-Konstrukt schneller.

    Hier mal ein anderer Anwendungsfall, mit dem ich auch vorhin im VC6 gemessen habe:

    #include <windows.h>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int FindC( const char* const cText, const char c )
    {
       const char* p = cText;
       while ( *p )
          if ( *p++ == c )
             return p - cText - 1;
       return -1;
    }
    
    int main()
    {
       const char* const foo = "0123456789abcdefghijklmnopqrstuvwxyz";
       int iFooLen = strlen( foo );
       string bar = foo;
       int runs = 1000000;
    
       for(unsigned u=0; u<10; u++)
       {
          DWORD dwStart = GetTickCount();
    
          switch(u&1)
          {
             case 0: {
                        for ( int i = 0; i < runs; ++i)
                            for( int j = 0; j < iFooLen; ++j )
                                bar.find( bar[j] );
                        break;
                     }
             case 1: {
    
                        for ( int i = 0; i < runs; ++i)
                            for( int j = 0; j < iFooLen; ++j )
                                FindC(foo, foo[j] );
                        break;
                    }
          }
          DWORD dwDuration = GetTickCount() - dwStart;
          switch(u&1)
          {
             case 0: cout << "string: " << dwDuration << " ms" << endl; break;
             case 1: cout << "FindC : " << dwDuration << " ms" << endl; break;
          }
       }
    }
    

    Und wenn ich mir noch die Messungen der anderen hier ansehe, kann man wirklich keine "Wahrheit" finden.... 10 User = 10 Systeme = 10 Meinungen....



  • Hier mal ein anderer Anwendungsfall, mit dem ich auch vorhin im VC6 gemessen habe

    Wenn du ernst genommen werden willst, dann solltest du einen modernen Compiler benutzen.



  • Da C und C++ hier fast das gleiche machen wundert es nicht dass das Ergebnis ähnlich ist. Hier hat mal jemand was über Raytracer geschrieben, welcher jedes Semester neu an einer Uni implementiert wird und hier zeugt sich das wenig überraschende Bild das C am schnellsten ist gefolgt von C++ und etwas die 4fache Zeit benötigt Java.

    Schneller wie in C geht es nur mit Assembler alles andere ist großer Humbug.


Anmelden zum Antworten