Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Compileroptimierung: Was passiert? (https://www.delphipraxis.net/55873-compileroptimierung-passiert.html)

yankee 28. Okt 2005 04:53


Compileroptimierung: Was passiert?
 
Als ich mit c++ angefangen habe, hatte ich in meinen Tutorials immer auch gleich Hinweise, wie die Compileroptimierung funzt. Also mit C++ bin ich noch ganz am Anfang und weiß kaum was darüber, aber bei Delphi weiß ich garnichts darüber.

Ich habe zum Beispiel hier gelesen, dass man result in Funktionen besser nicht benutzen sollte. Also ist die C++-Lösung (mit return) dann doch eigentlich besser. Zumindest zum Verständnis. Wenn es Delphi aber schon mit result macht, dann würde ich denken, dass die Compileroptimierung darauf eingestellt ist, dass man result auch richtig benutzt.

Naja, irgendwie versuche ich beim Programmieren schon öfters mal darüber nach, was die Compileroptimierung mit meinem Code so macht. Also ist es jetzt egal, ob man inc(a) oder a :=a +1 benutzt? Wie sieht es mit inline-Funktionen aus? So "richtig" gibt es die ja in Delphi nicht, aber eigentlich habe ich bis jetzt schon angenimmen, das die Compileroptimierung sehr kurze Funktionen dann doch als inline compiliert. Was ist, wenn ich mit div statt mit / dividiere? Ich könnte ja auch trunc oder round benutzen, um wieder einen integer zu bekommen. Macht da die Compileroptimierung was mit? Wie sieht es mit solchen Aufrufen aus:
Delphi-Quellcode:
type TZeug= record;
var1: integer;
var2: string;
end;
var bla: array of TZeug;
setlength(bla, length(bla) +1);
bla[length(bla) -1].var1 :=1;
bla[length(bla) -1].var2 :='bla';
macht die compileroptimierung draus was besseres oder berechnet der dann length(bla) wirklich 3 mal?

Was ist mit Konstanten? Geht der Compiler da einfach von oben nach unter durch und ersetzt alle constanten durch ihre Werte, oder gibt es da was tiefsinnigeres?
Was ist eigenlich mit Pointern? Also ist es besser zu versuchen in einem array den key zu meiden und stattdessen einen Pointer auf das arrayitem zu verwenden oder ist das garnicht schneller? (Also besonders wenn man einen array aus records hat und die Element bezug aufeinander haben. Soll man da einen Pointer nehmen, oder lieber den key als integer im record speichern? Grundätzlich ist der key ja praktischer, weil man dann auch in dem array das vorhergende Element oder sowas rankommt. Wenn Pionter wirklich schnelle sind: Darf man dafür hinnehmen, das gewisse Sachen iterativ nicht mehr lösbar sind? (Also beispielsweise einen Stammbaum, wo es immer Mutter und Vater gibt. Dort muss man dann schließlich rekursiv jeden der Beiden Zweige durchgehen, wenn man eine Aktion mit allen Elementen durchführen will, und alles nur mit New() und Dispose() statt mit array gelöst ist. Achja, wenn man einen array iteriert (bei PHP gibt es ja foreach dafür), also mit for i:=0 to count(array)-1 do, erkennt der compiler das und macht da irgendwas besseres draus?
mit while(i<100) do inc(i); ist soviel langsamer als die Version mit for. Was macht der Compiler mit for soviel anders?

Also wirklich sehr viele Fragen zur Codeoptimierung und Compileroptimierung. Ich fände es mal äußerst interessant zu wissen, wie der Compiler da vorgeht. Und vielleicht ein Vergeleich zu andern Compilern? Haben die C++-Compiler wirklich eine besser Optimierung? Wie sieht das eigentlich mit PHP aus? Da sind die Möglichkeiten ja sehr eingeschränkt bis nicht vorhanden. Was macht der Interpreter da?

jim_raynor 28. Okt 2005 06:23

Re: Compileroptimierung: Was passiert?
 
Kann jetzt nicht alles im Detail beantworten. Aber ein paar Sachen schon.

inc(i) ist besser als i:=i+1. Da bei dem zweiten Konstrukt quasi eine temporäre Variable erzeugt wird und bei inc direkt der speicherbereich der Variablen um 1 erhöht wird.

Das mit result resultiert glaube daraus, dass diese immer im einem Register abgelegt wird. Bedeutet also, wenn du direkt in der ersten Zeile der Funktion result:=1 schreibst, dann wird das register bis zum Prozedur ende belegt und steht für Schleifen nicht mehr zur Verfügung.

Bei div und / liegt der unterschied in den Assembler Anweisungen. Bei / wird die FPU genutzt (muss ja) und diese ist langsamer als die Integer-Division.

Sicherlich sind Pointer auf einen Array-Eintrag besser. Aber in einer Konstruktion wie

Delphi-Quellcode:
for i:=0 to 10 do
  Arr[i]:=10;
erzeugt Delphi automatisch einen Pointer und zählt diesen immer hoch bzw. runter. Bei schleifen wird nämlich immer versucht eine Prüfung gen 0 zu erreichen, da diese schneller ist als die Prüfung gegen 10.

Naja erstmal ein paar Sachen für den Anfang :)

teebee 28. Okt 2005 07:38

Re: Compileroptimierung: Was passiert?
 
Zitat:

Zitat von jim_raynor
inc(i) ist besser als i:=i+1. Da bei dem zweiten Konstrukt quasi eine temporäre Variable erzeugt wird und bei inc direkt der speicherbereich der Variablen um 1 erhöht wird.

Aus 'inc(i,x);' und 'i := i+x;' macht Delphi den selben Maschinencode.
Gruß, teebee

Robert Marquardt 28. Okt 2005 07:39

Re: Compileroptimierung: Was passiert?
 
Also "Inc(I)" und "I := I + 1;" werden vom Compiler zu ein und demselben Code verarbeitet.

Seit Delphi 7 laeuft eine for-Schleife abwaerts sofern es die Statements im Block der Schleife erlauben.
for- und while-Schleife sind nur in C synonym. In Pascal wird die obere Grenze nur einmal ausgewertet.
Zusaetzlich ist die Schleifenvariable insofern priviligiert als es nicht garantiert ist das nach Ablauf der Schleife der Wert garantiert ist (siehe obige Richtungsoptimierung).
Vermutlich optimiert der Compiler eine leere for-Schleife komplett weg.

Bei Konstanten muss man typisierte und untypisierte Konstanten unterscheiden.
Typisierte Konstanten werden durch Variablen implementiert. Bei untypisierte Konstanten setzt der Compiler den Wert direkt in den generierten Code.
Eine textuelle Ersetzung ist nur beim C Präprozessor vorhanden, der eine eigene Sprache bildet.

schöni 28. Okt 2005 08:47

Re: Compileroptimierung: Was passiert?
 
Hallo yankee!

Mit Deinen Überlegungen bringst Du mich auf die Idee, den Quellcode für eine Aufgabenstellung in verschiedenen Versionen zu schreiben, das Ganze dann mit vollständiger Debuginfo zu übersetzen und dann nicht nur auf Quelltextebene, sondern auch mit Hilfe des CPU-Fensters zu analysieren, das es seit Delphi 4 gibt. Dann sihst Du am besten, was der Compiler aus dem Code macht. Mit Laufzeitmessungen kannst Du auch noch die Performance messen. Da habe ich aber die aufzurufenden Prozeduren jtzt nicht im Kopf:

Auf jeden Fall:

Zeitmessung starten

Die eigene Prozedur aufrufen

Zeitmessung stoppen

Ergenis anzeigen

schöni

DerDan 28. Okt 2005 10:37

Re: Compileroptimierung: Was passiert?
 
Zitat:

Zitat von schöni
Hallo yankee!

Mit Deinen Überlegungen bringst Du mich auf die Idee, den Quellcode für eine Aufgabenstellung in verschiedenen Versionen zu schreiben, das Ganze dann mit vollständiger Debuginfo zu übersetzen und dann nicht nur auf Quelltextebene, sondern auch mit Hilfe des CPU-Fensters zu analysieren, das es seit Delphi 4 gibt. Dann sihst Du am besten, was der Compiler aus dem Code macht. Mit Laufzeitmessungen kannst Du auch noch die Performance messen. Da habe ich aber die aufzurufenden Prozeduren jtzt nicht im Kopf:

Auf jeden Fall:

Zeitmessung starten

Die eigene Prozedur aufrufen

Zeitmessung stoppen

Ergenis anzeigen

schöni

Aus anderen Compilern ist mir bekannt, das mit vollständigem Debug, manche Optimierungen abgeschaltet werden. Ist bei Delphi wahrscheinlich auch so! Das sollt man dan schon mal berücksichtigen!


mfg DerDan

alzaimar 28. Okt 2005 10:42

Re: Compileroptimierung: Was passiert?
 
Zitat:

Zitat von DerDan
Aus anderen Compilern ist mir bekannt, das mit vollständigem Debug, manche Optimierungen abgeschaltet werden. Ist bei Delphi wahrscheinlich auch so! Das sollt man dan schon mal berücksichtigen!
mfg DerDan

Ist mir nicht bekannt.

LarsMiddendorf 28. Okt 2005 10:43

Re: Compileroptimierung: Was passiert?
 
Zitat:

Wie sieht es mit inline-Funktionen aus? So "richtig" gibt es die ja in Delphi nicht, aber eigentlich habe ich bis jetzt schon angenimmen, das die Compileroptimierung sehr kurze Funktionen dann doch als inline compiliert.
Ab Delphi2005 gibt es inline Funktionen. Allerdings mit einigen Einschränkungen so dass nicht alle Funktionen geinlined werden.
Bei Delphi.Net werden automatisch alle Funktionen die nicht länger als 32 Befehle sind und keine Schleifen,case of oder Exception Blöcke enthalten geinlined.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz