Warum programmiert ihr in C?
-
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.
-
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 msAufruf: 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:
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.
-
Realistisch schrieb:
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++
Laß echte Fachleute ran und C++ ist schneller als C.
-
Es gibt ja auch in Wirklichkeit kein richtiges C++, das ist alles ein abgewandeltes C mit Zusatzkram. C++ läßt sich somit nicht vollständig ohne C programmieren.
-
Hab ich ja jetzt auch mit nem besseren Compiler gemessen.
- MinGW
- VS2008#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 FindC2( const char* const cText, const char c , int iLen) { const char *p = (const char *)memchr(cText, c, iLen); if(p) return p - cText; return -1; } int main() { const char* const foo = "aaaaaa"; // const char* const foo = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; int iLen = strlen(foo); string bar = foo; int runs = 10000000; for(unsigned u=0; u<12; u++) { int c = 0; DWORD dwStart = GetTickCount(); switch(u % 3) { case 0: for(int i = 0; i < runs; ++i) c = bar.find('w'); break; case 1: for(int i = 0; i < runs; ++i) c = FindC(foo, 'w'); break; case 2: for(int i = 0; i < runs; ++i) c = FindC2(foo, 'w', iLen); break; } DWORD dwDuration = GetTickCount() - dwStart; switch(u % 3) { case 0: cout << "string: (" << c << ") " << dwDuration << " ms" << endl; break; case 1: cout << "FindC : (" << c << ") " << dwDuration << " ms" << endl; break; case 2: cout << "FindC2: (" << c << ") " << dwDuration << " ms" << endl; break; } } }
Wer Lust hat kann das ja mal mit VS2008 messen und dabei unterschiedlich lange Strings verwenden. Die Variante FindC2 ist hier eine Imitation der STL-Implementierung von std::string::find(...). Der verwenden nämlich memchr(...) und das is relativ fix bei langen strings, aber nicht so schnell bei sehr kurzen strings. Scheint also bissel Overhead zu haben.
Hier mal noch die Messungen mit MinGW:
1.Langer String
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaastd::string::find - 297ms
FindC - 343ms
FindC2 - 219ms2.Kurzer String
aaaaaastd::string::find - 172ms
FindC - 47ms
FindC2 - 94msWer Lust und Laune hat, kann sich ja auch mal den ASM-Code für die zwei FindC-Funktionen anschauen.
-
Finde zwar nichts was bestätigen würde, dass einige Teile von der STL in Assembler programmiert sind, doch ich vermute es zumindest.
Klar ist C schneller als C++, in manchen Gebieten, dass wissen wir beide!
Du musst das Zeug's mehrfach messen und dan den Schnitt nehmen !
-
Hab ich natürlich gemacht. Das sind Durchschnittswerte von mehreren Messungen für jede der drei Funktionen. Schon allein um irgendwelche Seiteneffekte auszuschließen.
Aber Aussage ist ja eigentlich, dass derartige Diskussionen mehr als müßig sind und nicht nur von Compiler oder Prozessor abhängen sondern auch vom Anwendungsfall wie man hier beim Vergleich der kurzen und langen Strings deutlich sieht.
-
-lowbyte- schrieb:
Finde zwar nichts was bestätigen würde, dass einige Teile von der STL in Assembler programmiert sind, doch ich vermute es zumindest.
Soweit ich weiß, ist alles in der stl ist normal programmiert. Aber mir scheint, bei MS kennt der Optimierer manche Funktionen wie std::swap sehr genau und zaubert dort.
Klar ist C schneller als C++, in manchen Gebieten, dass wissen wir beide!
Hoffen wir, daß wir auch beide wissen, daß C++ in manchen Gebieten schneller ist.
Du musst das Zeug's mehrfach messen und dan den Schnitt nehmen !
Unfug. Man muß den kleinsten Wert nehmen.
-
Okey klar ! Aber kannste nicht garantieren dass sie wirklich immer so schnell ist.
-
-lowbyte- schrieb:
Warum ? Das heisst nach deiner Meinung, dass ich nicht sicher sein kann dass sie ihre Leistung erbringt ! Wenn du vom Tiefsten Wert ausgehst ...
Die Zeitungenauigkeiten kommen, wenn Windows Dir den Prozess wiedermal für 10ms wegnimmt, die exe-Datei noch nicht ganz im RAM war, und so Sachen. Deswegen machst Du so viele Messungen, bis mal zufällig keine Fremdverlangsamung vorlag.
Was bei dieser Messung am schnellsten war, ist dann auch durchschnittlich am schnellsten.
Bei Meßzeiten im Minutenbereich bekommt man beim Minimummessen fünf stabile Stellen. Diese Kleinigkeit sollte auf den Takt genau ausmessbar sein.
-
Also bei den Messungen gab es nur Unterschiede von 1-2ms, also nicht der Rede wert und macht in dem Fall auch keinen Unterschied ob man den kleinsten Wert oder den Durchschnitt nimmt.
Zumindest hatte ich so mal ein wenig Antrieb hinter die Fassade der STL zu schauen und hab dabei sogar noch eine tolle Funktion entdeckt ( memchr )
Die STL kocht also auch nur mit Wasser... Kein Grund zur Panik