Rechenkünstler - Compiler vergleich
-
Hi,
mir war etwas langweilig und da hab ich mir gedacht, ich guck mir mal ein paar verschiedene Compieler an und guck mal was die so für Code erstellen.
Mein Test Code war dieser:
int i = 0; int j = 0; SYSTEMTIME tSystemTimeStart; SYSTEMTIME tSystemTimeEnd; GetSystemTime(&tSystemTimeStart); while (j != 100) { while (i != 99999999) { i = i + 1; } i = 0; j = j + 1; } GetSystemTime(&tSystemTimeEnd);
am ende hab ich den Unterschied in Millisekunden ausgerechnet und ausgegeben. Das Ergebniss war schon etwas verwundert.
Also die Grösse der Dateien variert extrem...
VisualC++ 73.728 Byte
Borland: 272.384 Byte
DevC++: 475.842 Bytenaja... und beim Ausführen war ich bav!
VisualC++: 23703 MilliSec
Borland: 7735 MilliSec
DevC++: 16531 MilliSec...so jetzt denk ich mal, das es an den Optierungen welche beim Compiler eingestellt waren liegt. Ich habe alle alle Programme mit dem default Einstellungen erstellen lassen (da ich mich mit Borland und DevC++ nicht auskenne und dadurch nur am VisualC++ was hätte drehen können).
=> Meine Frage: Erstellt der Borland wirklich so optimiert Code? Ich denk mal das man eh das Programm nicht als Massstab nehmen kann... Aber trozdem bin ich etwas verwundert
- woran liegt das?
-
Borland erstellt wirklich schnelleren Code.
Ich hab vor ~2 Jahren mal an einem Codingwettbewerb teilgenommen, dabei ging es um das schnellste sortieren von 1.000.000 Elementen beliebigen Typs mit iterativem und rekusivem Merge- und Quicksort. Da kamen wir zu aehnlichen Ergebnissen. Borland war der schnellste Compiler mit 1.000.000 Elemente in unter 2 sec sortiert (iterativer Quicksort), danach kam VC6 mit 3.5 und g++ mit knapp ueber 4.Woran das aber genau liegt kann ich dir nicht sagen. Dein Programm ist eigentlich schon so, dass man durch umschreiben von Code nicht viel machen kann ohne den Code zu veraendern. Ich weiss, dass zum Beispiel konstante for-schleifen (for i=1 to 10) gerne wegoprimiert werden und der Code einfach 10 mal hingeschrieben wird, aber das haben wir hier ja nicht. Und auch keine Funktionsaufrufe. Interessantes Beispiel. Werd mal bisschen experimentieren *g*.
-
Hast du auch die Zeit gemessen die der Compiler braucht? Da wirst du bei Borland mit den Ohren schlackern, wenn du ein größeres Projekt hast und einen langsamen PC.
-
Die Compilezeit spielt absolut keine Rolle (für eine Releaseversion). Hauptsache es läuft ausgeliefert anständig schnell.
Zur Dateigröße, der Gnu Compiler heftet gerne viele Debug-Symbole dran. Wenn man die wegstrippt, dann sollten die Executables vom Gnu auch recht klein sein.
Von einem guten Compiler würde ich erwarten, dass er zumindest die innere Schleife vollständig wegoptimiert. Mit aktviertem Loop-Unrolling sollte er meine ich auch die äußere packen können. Würd mich da aber auch nicht 100%ig festlegen wollen.
Probier mal, dem Gnu den Schalter -O2 mitzugeben - evtl. sogar -O3. Beim Borland kann man einstellen, dass man ein Releasebuild erzeugen will. Das ist ein Preset für Geschwindigkeits-Optimierungen. Geht irgendwo in den Compiler-Optionen.
-
7H3 N4C3R schrieb:
Die Compilezeit spielt absolut keine Rolle (für eine Releaseversion). Hauptsache es läuft ausgeliefert anständig schnell.
Die Compilezeit spielt aber eine Rolle für den Programmierer und das sind wir hier oder? Was man dadurch an Arbeitszeit verplempern kann ist ein Fass ohne Boden. AFAIR steht sogar in der Borland Hilfe eine Antwort auf die häufige Frage warum der Compiler so langsam ist.
-
Ich hab das ganze mal dem gcc zu futtern gegeben (halt mit time() statt der Windowsfunktion).
ohne Optimierung: 9260 Bytes, 19 sec
mit O3: 9212 Bytes, 7 sec
-
asdrubael schrieb:
7H3 N4C3R schrieb:
Die Compilezeit spielt absolut keine Rolle (für eine Releaseversion). Hauptsache es läuft ausgeliefert anständig schnell.
Die Compilezeit spielt aber eine Rolle für den Programmierer und das sind wir hier oder? Was man dadurch an Arbeitszeit verplempern kann ist ein Fass ohne Boden. AFAIR steht sogar in der Borland Hilfe eine Antwort auf die häufige Frage warum der Compiler so langsam ist.
einfache lösung:
der programmierer will das programm nur testen? debugbuild->der is auch schnell
will er das programm veröffentlichen? releasebuild.
-
Dieser Test ist völlig irrelevant, da das in der Realität keiner so macht. Ein guter Compiler sollte alles wegoptimieren können. Ich hab mal folgenden Code dem LLVM gegeben:
int main() { int i = 0; int j = 0; while (j != 100) { while (i != 99999999) { i = i + 1; } i = 0; j = j + 1; } }
Das Ergebnis ist folgender Bytecode:
target endian = little target pointersize = 32 target triple = "i686-pc-linux-gnu" deplibs = [ "stdc++", "c", "crtend" ] implementation ; Functions: int %main() { entry: call void %__main( ) ret int 0 } declare void %__main()
Selbst wenn man den Bytecode nicht kennt, sieht man dass er hier rein gar nichts macht.
-
pli schrieb:
...so jetzt denk ich mal, das es an den Optierungen welche beim Compiler eingestellt waren liegt. Ich habe alle alle Programme mit dem default Einstellungen erstellen lassen (da ich mich mit Borland und DevC++ nicht auskenne und dadurch nur am VisualC++ was hätte drehen können).
dann wird den test gleich mal weg.
du testest ja nur, welcher compiler die schlechtesten oder die wenigsten debug-hilfen hat.=> Meine Frage: Erstellt der Borland wirklich so optimiert Code?
unwahrscheinlich. lass es uns einfach mal ausmessen. und zwar mit den besten compileroptionen.
Ich denk mal das man eh das Programm nicht als Massstab nehmen kann...
stimmt auch. man sollte schon irgendwelche berechnungen machen, die nicht offensichtlich wegoptimiert werden können.
-
VC6/7 optimiert im Release-Modus auch alles weg.
otze schrieb:
der programmierer will das programm nur testen? debugbuild->der is auch schnell
Schnell ist bekanntlich Ansichtssache, aber das gehört nicht hierher. Was ich damit sagen wollte ist, das kleine Executables und schnelle Laufzeiten nicht alles sind was einen "guten" Compiler ausmacht.
-
Ein "guter" Compiler ist so konfigurierbar, dass man während der Codierung auch mal schnell testen kann ohne ewig zu warten.
-
Mit solchen Microbenchmarks sollte man sehr vorsichtig sein denn eigenmtlich sagen sie so gut wie nichts über das LAufzeitverhalten eines Programms aus.
Du brücksichtigst hier nur ein paar Loops und primitive Integerarithmetik.Ich hab auch mal ein paar solcher Test gemacht. Die Ergebnisse waren extrem durchwachsen. Gleitkommaarithmetik war zum Beispiel auf dem GNU-Compiler und dem MS-Compiler nahezu gleich gut. Der Borland Compiler hat hier teilweise langsameren Code erzeugt. Auch C# hab ich mal so "gebenchmarkt". Die Ergenisse waren auch recht ungewöhnlich:
Code mit Sinus und Cosinusfunktionen liefen bei Gnu z.B. deutlich langsamer als bei C#, dafür war aber normale Arithmetik schneller.Du siehst, dass solche Benchmarks - je nachdem was man testet - recht unterschiedlich Ergebnisse bringen können.
-
Abhängig von den eingestellten Optionen des Compilers bzw. der Entwicklungsumgebung wird der Entwicklungs- und Programmierprozess beschleunigt (die Compilierzeit veringert) und die Dateigrösse veringert.
Die Programme sind dann aber nur auf Rechnern lauffähig, auf denen der Compiler oder die Entwicklungsumgebung installiert ist.
Aber selbst bei vollständig compilierten Programmen ist z.B. zu beachten, ob Komentare/Fehlerprotokolle mit integriert wurden.
-
Danke für das Feedback...
Wie ich schon gesagt hab: "Ich denk mal das man eh das Programm nicht als Messstab nehmen kann..."
Aber das Ergebnis hat mich halt doch etwas überrascht...Das sie nichts über die Laufzeitverhalten eines Programms aussagen war mir schon klar... da kommt dann Berechnungen, HD / RAM I/O und und und dazu...
Ich fand nur das Ergebnis Interessant... (und wollte etwas zum Diskutieren anstossen)