Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Was ist schneller, Funktion oder Prozedure? (https://www.delphipraxis.net/55903-ist-schneller-funktion-oder-prozedure.html)

Angel4585 28. Okt 2005 13:36


Was ist schneller, Funktion oder Prozedure?
 
Also ich hab einmal
Delphi-Quellcode:
Procedure x(var Arg : integer);
begin
Arg:=0;
end;
und

Delphi-Quellcode:
function y:integer;
begin
Result:=0;
end;
die ja beide glaube ich das selbe machen

einziger Unterschiede ist der AUfruf :

Delphi-Quellcode:
x(erg);
Delphi-Quellcode:
erg:=y;
Aber Sind Beide genau gleichschnell in der Ausführung oder ist eins schneller?


Edit: :hello: ich hab die no bashing signatur JUHU :party:

Neotracer64 28. Okt 2005 14:20

Re: Was ist schneller, Funktion oder Prozedure?
 
Teste es doch mal :)

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  lol,lol2: Int64;
  v: Integer;
begin
  QueryPerformanceCounter(lol);
  x(v);
  QueryPerformanceCounter(lol2);
  Label1.Caption := IntToStr(lol2-lol);

  QueryPerformanceCounter(lol);
  v := y;
  QueryPerformanceCounter(lol2);

  Label2.Caption := IntToStr(lol2-lol);
end;

malo 28. Okt 2005 14:24

Re: Was ist schneller, Funktion oder Prozedure?
 
Ich denke, wenn es Performence-Unterschiede gibt, dann ist die function langsamer, weil dort noch ein Rückgabewert gespeichert wird. Aber das ist so minimal, dass der Unterschied nicht spürbar ist. Es wird halt höchstens noch eine Variable mehr gespeichert, mehr passiert nicht ;)

Edit: Schmarn, es ging ja darum, dass bei der Procedure eine Variable per Parameter zurückgegeben wird. :oops:

Angel4585 28. Okt 2005 14:25

Re: Was ist schneller, Funktion oder Prozedure?
 
Hmm.. Funktion ist schneller, Prozedur schwankt zwischen 4 und 5, Funktion konstant bei 3

(bedeutet doch das funtion schneller ist oder?)

sakura 28. Okt 2005 14:26

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von Angel4585
Hmm.. Funktion ist schneller, Prozedur schwankt zwischen 4 und 5, Funktion konstant bei 3

(bedeutet doch das funtion schneller ist oder?)

Setze das ganze mal in eine Schleife und lasse diese 100000 Mal laufen. Alles andere ist zu kurz für einen guten Mittelwert ;)

...:cat:...

Neotracer64 28. Okt 2005 14:31

Re: Was ist schneller, Funktion oder Prozedure?
 
Dann halt

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  lol,lol2: Int64;
  v: Integer;
  i: Integer;
begin

  QueryPerformanceCounter(lol);
  For i := 1 To 100000 Do
    begin
     x(v);
    end;
  QueryPerformanceCounter(lol2);

  Label1.Caption := IntToStr(lol2-lol);


  QueryPerformanceCounter(lol);
  For i := 1 To 100000 Do
    begin
     v := y;
    end;
  QueryPerformanceCounter(lol2);

  Label2.Caption := IntToStr(lol2-lol);
end;
Funktion is bei mir schneller :)

Angel4585 28. Okt 2005 14:32

Re: Was ist schneller, Funktion oder Prozedure?
 
WOW, das ändert das ganze schon beträchtlich : Prozedur liegt bei 3,107773 Funktion bei 3,087948

Edit :
Delphi-Quellcode:
var
  lol,lol2: Int64;
  v,w,i: Integer;
const anz = 1000000 ;
begin
  w:=0;
  for i:= 1 to anz do
   begin
   QueryPerformanceCounter(lol);
   xx(v);
   QueryPerformanceCounter(lol2);
   w:=w+ lol2-lol;
   end;
  Label1.Caption := FloatToStr(w/anz );

  w:=0;
  for i:= 1 to anz do
   begin
   QueryPerformanceCounter(lol);
   v:=y;
   QueryPerformanceCounter(lol2);
   w:=w+ lol2-lol;
   end;
  Label2.Caption := FloatToStr(w/anz );
end;
bei anz = 10000000 wird plötzlich die Prozedur schneller (3,14 für prozedure und 3,26 für Funktion)

sakura 28. Okt 2005 14:35

Re: Was ist schneller, Funktion oder Prozedure?
 
Damit kannst Du sagen: nutze das, was Dir an der Stelle beim Schreiben mehr nutzen bringt (wahrscheinlich die Funktion), da der Geschwindigkeitsunterschied vernachlässigbar gering ausfällt ;)

...:cat:...

Flocke 28. Okt 2005 14:39

Re: Was ist schneller, Funktion oder Prozedure?
 
Du solltest allerdings die Aufrufe von QueryPerformanceCounter aus der Schleife herausnehmen und jeweils nur zwei Mal aufrufen - das verfälscht doch beträchtlich.

Angel4585 28. Okt 2005 14:40

Re: Was ist schneller, Funktion oder Prozedure?
 
:wiejetzt: :gruebel:

nach 100.000.000 ist wieder die Funktion vorne...

naja ich muss dann bald mal .. schönes WE euch allen

bigg 28. Okt 2005 14:46

Re: Was ist schneller, Funktion oder Prozedure?
 
Ist eine Prozedur nicht eine Funktion,
bei der der Rückgabewert immer #0 ist?

Neotracer64 28. Okt 2005 14:52

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

nach 100.000.000 ist wieder die Funktion vorne...
Bei meinen test ist immer die Funktion vorne.
Du kannst ja danach den ermittelten Wert nochma teilen.

Flocke 28. Okt 2005 14:52

Re: Was ist schneller, Funktion oder Prozedure?
 
@Angel4585: Besser so, sonst misst du ja fast nur die Laufzeit von QueryPerformanceCounter und nicht von deiner Funktion/Prozedur :wink:

Delphi-Quellcode:
var
  lol,lol2: Int64;
  i: Integer;
const anz = 1000000 ;
begin
  QueryPerformanceCounter(lol);
  for i:= 1 to anz do
   begin
   xx(v);
   end;
  QueryPerformanceCounter(lol2);
  Label1.Caption := FloatToStr((lol2-lol)/anz );

  QueryPerformanceCounter(lol);
  for i:= 1 to anz do
   begin
   v:=y;
   end;
  QueryPerformanceCounter(lol2);
  Label2.Caption := FloatToStr((lol2-lol)/anz );
end;

Angel4585 28. Okt 2005 14:55

Re: Was ist schneller, Funktion oder Prozedure?
 
ach die misst sich selber auch mit?? ist ja besch...

schönes WE zusammen

SMO 28. Okt 2005 15:01

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von Angel4585
die ja beide glaube ich das selbe machen

Jein. Da kommt die Optimierung des Delphicompilers ins Spiel. Wie du vielleicht weißt, repräsentieren Variablen normalerweise Speicherzellen im RAM. Wenn ich also eine Zuweisung wie "erg := 2" habe, dann wird eine bestimmte Speicheradresse, die für "erg" reserviert wurde, mit dem Wert 2 gefüllt. Nun können Speicherzugriffe allerdings relativ viel Zeit kosten, da der Hauptspeicher ziemlich viel langsamer ist als modernen Prozessoren. Deshalb sollte man Speicherzugriffe wenn möglich vermeiden.

Prozessoren haben eigene kleine Speicherbereiche, die sogenannten Register. Kann man sich als Variablen vorstellen, die direkt in der CPU integriert und daher sehr schnell sind. Delphi-Variablen werden deshalb wann immer möglich auf Register abgebildet und nicht auf Speicherzellen im RAM.

Je nachdem wie der Kontext deines Programms nun aussieht, ist es möglich, dass "erg" auf ein Register abgebildet wird. In dem Fall wäre ein Funktionsaufruf à la "erg := y" vorzuziehen, denn dabei muss kein Speicherzugriff getätigt werden, das Funktionsergebnis wird einfach und schnell von Register zu Register kopiert (falls überhaupt).

Durch einen "var" Parameter dagegen erzwingst du sogar, dass die Variable, die als Parameter übergeben wird, im Speicher liegt und kein Register sein kann. D.h. selbst wenn dein Programmabschnitt vom Compiler so optimiert werden könnte, dass "erg" immer in einem Register gehalten werden kann und nie in den Speicher geschrieben werden muss, macht ein Prozeduraufruf à la "x(erg)" diese Optimiertungsmöglichkeit zunichte und verursacht, dass "erg" auf jeden Fall eine Speichervariable wird.

Allerdings dürften die Unterschiede so gering ausfallen, dass es sich eigentlich nicht lohnt, sich darüber den Kopf zu zerbrechen. ;)
Aber natürlich ist es immer interessant zu wissen, wie das ganze eigentlich intern abläuft. Wenn man z.B. eine Funktion deklariert, deren Rückgabewert nicht sinnvoll in Registern gehalten werden kann, dann baut der Delphicompiler das automatisch in eine Prozedur mit var Parameter um. So wird z.B. aus "function ErzeugeBmpHeader: TBitmapInfoHeader" intern ein "procedure ErzeugeBmpHeader(var Result: TBitmapInfoHeader)".

Fazit: Bei elementaren Datentypen (Byte, Word, Integer usw.) sind Funktionen vorzuziehen, bei komplexen Datentypen gibt's sowieso keinen Unterschied.

himitsu 28. Okt 2005 15:02

Re: Was ist schneller, Funktion oder Prozedure?
 
Also, nach den Hilfetexten zum ASM in der OH, kann man eigentlich sagen, daß beides entweder beides gleich schnell, die Funktion schneller, oder auch die Prozedur schneller ist.

Es kommt halt nur darauf an von welchem Typ das Result ist, da je nach Datentyp eine andere Methode verwendet wird.
Oder was direkt nach der Funktion/Prozedur mit dem Parameter/Result angestellt wird.


Eine pauschale Antwort was nun schneller ist kann zu 100% keiner geben.


Wenn allerdings eine bestimmte Funktionalität (Typ des Parameters und dessen Verwendungsweise außerhalb der Funktion/Prozedur) vorliegt, dann wäre eine Aussage über die vermutlich bessere (z.B. schneller) Variante möglich.

dizzy 28. Okt 2005 15:17

Re: Was ist schneller, Funktion oder Prozedure?
 
Letztendliche Gewissheit bringt nur ein Durchsteppen durch das CPU-Fenster.

...was ich nun auch mal getan habe:
Code:
function y: Integer;
----------------------
  CALL y
  XOR  eax, eax  // Inhalt von eax 0 setzen
  RET             // Rücksprung

  MOV [esp],eax  // Zuweisung an lokale Variable erg (In Aufrufermethode)



procedure x(var Arg : integer);
----------------------
  MOV  eax, esp // In esp steht der Pointer auf die lokale Variable erg; diesen als Parameter laden (In Aufrufermethode)
  CALL x

  XOR  edx, edx // einfach in einem freien Register eine 0 erzeugen
  MOV [eax],edx // und an die Speicherstelle schreiben
  RET            // Rücksprung
Damit steht die Prozedur mit einer Anweisung mehr prinzipiell schlechter da. Jedoch bleibt die Frage wie stark die CPU selbst mit Caching usw. da noch mitspielt. Zudem ist der erzeugte Code sicherlich abhängig davon in welchem Kontext er sich befindet.

\\edit: Drüber hinaus müsste die erste Anweisung bei der Prozedur nur ein einziges Mal vor Ausführung einer Schleife (zumindest bei obiger) ausgeführt werden, solange zwischendrin EAX unangetastet bleibt. Somit wären sie in einer Messung in einer Schleife vermutlich (in diesem Fall!) gleich schnell. Das XOR ließe sich an dieser Stelle in diesem Fall auch bei mehrfachem Aufruf sparen, so edx nicht anderweitig verändert wird, aber da dies in einer ausgelagerten Prozedur geschieht die nichts darüber wissen kann, wird es auch in einer Schleife bestehen bleiben. Da kann der Optimierer nicht dran - mit Inlining hätte er hier also sogar einen doppelten Vorteil: Einmal spart man sich den CALL, und zum zweiten ließe sich eine ganze Anweisug wegoptimieren. Ferner würde sich dann sogar erkennen lassen, dass v immer der selbe Wert zugewiesen wird, und der ganze Kram incl. Schleife könnte rausgeschmissen werden, und v ein einziges Mal mit einer Konstanten belegt... jaja, ich war schon immer Fan von Inlining ^^

Tubos 28. Okt 2005 15:33

Re: Was ist schneller, Funktion oder Prozedure?
 
Warum wird bei deiner Prozedur ein Parameter übergeben und bei der Funktion nicht?

dizzy 28. Okt 2005 15:35

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von Tubos
Warum wird bei deiner Prozedur ein Parameter übergeben und bei der Funktion nicht?

Weil es den Prozeduren des Threaderstellers gleicht ;)

dizzy 28. Okt 2005 15:38

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von himitsu
@Dizzy:
Du mußt bei dieser Betrachtung auch mit einbeziehen, wie die Funktion/Prozedur aufgerufen wird.
Also, es ist nicht nur das wichtig was innerhalb der Funktion/Prozedur geschieht, sondern auch wie der Parameter an die Funktion/Prozedur übergeben und zurückgenommen wird.

Dessen bin ich mir bewusst. Daher schrieb ich ja auch, dass es hier doch sehr stark auf den Kontext ankommt. Allein schon wenn man nicht "lose" Funktionen, sondern Klassenmethoden aufruft ändert sich einiges. Auch was sonst drumherum passiert kann das ganze Bild verändern. Eine pauschale Antwort ist hier also kaum machbar.

\\edit:
Zitat:

hat sich erledigt -.-''
:mrgreen:

SMO 28. Okt 2005 15:46

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Daher schrieb ich ja auch, dass es hier doch sehr stark auf den Kontext ankommt. Allein schon wenn man nicht "lose" Funktionen, sondern Klassenmethoden aufruft ändert sich einiges. Auch was sonst drumherum passiert kann das ganze Bild verändern. Eine pauschale Antwort ist hier also kaum machbar.

Eben. Deswegen bring ein Konkretes ASM-Beispiel kaum etwas. Je nach Kontext des Funktionsaufruf kann der generierte Code auch so aussehen:
Code:
function y: Integer;
----------------------
  CALL y
  XOR  eax, eax  // Inhalt von eax 0 setzen
  RET             // Rücksprung

  MOV esi,eax  // Zuweisung an lokale Variable erg, die sich nun im Register esi befindet
Das wäre nochmal ein Stückchen schneller, da man hier keinen Speicherzugriff hat. Unter Umständen kann der letzte Befehl "MOV esi,eax" sogar entfallen, nämlich dann wenn "erg" im Folgenden auf das Register eax abgebildet wird.

Wie ich oben bereits schrieb, Aufrufe mit var Parameter erzwingen immer eine Speichervariable. Deshalb kann man schon eine pauschale Aussage machen, nämlich: bei primitiven Datentypen Funktionen benutzen, kann der Optimierung dienlich sein.

RavenIV 28. Okt 2005 15:50

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von SMO
Wie ich oben bereits schrieb, Aufrufe mit var Parameter erzwingen immer eine Speichervariable. Deshalb kann man schon eine pauschale Aussage machen, nämlich: bei primitiven Datentypen Funktionen benutzen, kann der Optimierung dienlich sein.

eigentlich sollte man immer funktionen verwenden und auch immer ein wert zurückgeben.
denn auch in einer procedure kann mal etwas schiefgehen und das bekommt der aufrufer dann nicht mit.

himitsu 28. Okt 2005 15:57

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von RavenIV
eigentlich sollte man immer funktionen verwenden und auch immer ein wert zurückgeben.
denn auch in einer procedure kann mal etwas schiefgehen und das bekommt der aufrufer dann nicht mit.

Ob da nun als Parameter, oder Result-Parameter ... ist da doch egal?
Wobei bei einer Exception sogar ein Var-Parameter seine Vorteile haben kann, da man diesen ja am Anfang der Prozedur (vor einer eventuellen Exception) auf einen bestimmten Wert setzen kann, wärend bei der Funktion im Exceptionfall der Rückgabewert verloren geht.

Und wiso soll der Benutzer ausgerechnet nur bei Prozedur nichts mitbekommen, wenn was schiefgeht?

tommie-lie 28. Okt 2005 15:59

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von RavenIV
eigentlich sollte man immer funktionen verwenden und auch immer ein wert zurückgeben.
denn auch in einer procedure kann mal etwas schiefgehen und das bekommt der aufrufer dann nicht mit.

Und wie kriegt er es üblicherweise bei Funktionen mit? Richtig, Fehlercode im Ergebnis speichern. Das gleiche kannst du auch bei Prozeduren machen. Ansosnten wirf halt 'ne Exception, wenn du den Rest des Codes nicht so narrensicher schreiben willst, das tatsächlich nur eine Exception aus dem Betriebssystem dazwischenfunken könnte.

Tubos 28. Okt 2005 16:07

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Weil es den Prozeduren des Threaderstellers gleicht
Achja!
Rückgabe per parameter... hab ich komplett vergessen. War wohl ein Blackout ;)

Khabarakh 28. Okt 2005 17:19

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Da kann der Optimierer nicht dran - mit Inlining hätte er hier also sogar einen doppelten Vorteil: Einmal spart man sich den CALL, und zum zweiten ließe sich eine ganze Anweisug wegoptimieren. Ferner würde sich dann sogar erkennen lassen, dass v immer der selbe Wert zugewiesen wird, und der ganze Kram incl. Schleife könnte rausgeschmissen werden, und v ein einziges Mal mit einer Konstanten belegt... jaja, ich war schon immer Fan von Inlining ^^

Und hier der Test dazu:
Delphi-Quellcode:
procedure x(var AValue: Integer); inline;
begin
  AValue := 0;
end;

function y: Integer; inline;
begin
  Result := 0;
end;

var
  i: Integer;
begin
  x(i);
  i := y;
end.
http://img237.imageshack.us/img237/7222/temp2nh.png
Mein Wissen über Assembler tendiert zwar gegen null, aber das sieht für mich ziemlich ähnlich aus :stupid: . Die Geschwindigkeiten sollten wohl auch nah beieinander liegen :stupid:² . Von anderen Optimierungen sehe ich aber nichts.

dizzy 28. Okt 2005 17:23

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von Khabarakh
Mein Wissen über Assembler tendiert zwar gegen null, aber das sieht für mich ziemlich ähnlich aus :stupid: . Die Geschwindigkeiten sollten wohl auch nah beieinander liegen :stupid:² . Von anderen Optimierungen sehe ich aber nichts.

Ich habe von einer Schleife gesprochen. Mindestens ein Mal _muss_ das ja gemacht werden um eine Null zu erzeugen. Dein Test passt somit nicht zur Vermutung ;)

\\edit: Jedoch hast du insofern Recht, als dass das xor für die 2. Codezeile über ist, ja. Da scheint mir der Optimizer kaum optimal zu sein. Mit ein Grund weswegen ich scharf darauf bin manche Dinge in asm selbst von Hand machen zu können - ich kann dem Automatismus also nicht voll vertrauen :D

Khabarakh 28. Okt 2005 17:42

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
\\edit: Jedoch hast du insofern Recht, als dass das xor für die 2. Codezeile über ist, ja. Da scheint mir der Optimizer kaum optimal zu sein.

Genau, das habe ich gemeint. Die Schleife ändert übrigens auch nichts, es wird trotzdem 20.000-mal geXORt.

dizzy 28. Okt 2005 18:13

Re: Was ist schneller, Funktion oder Prozedure?
 
Mh, find ich nun fast enttäuschend. Dann heisst Inlining dort tatsächlich nur Ersparnis des Calls, bzw. der Vorbereitung der Parameter, und den Optimizer kümmerts nicht? In meinen Augen inkonsequent. In einem komplexeren Zusammenhang könnte ich ja verstehen dass da sicher nicht alles super-tip-top optimiert werden kann, da die Zusammenhänge sehr komplex werden können. Aber in so einem einfachen Fall dürfte das sehr wohl per Software erkennbar sein.
Aber nun back to Topic :stupid:

tommie-lie 28. Okt 2005 18:21

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Aber in so einem einfachen Fall dürfte das sehr wohl per Software erkennbar sein.

Ist es sicherlich, aber es muss implementiert werden. Und da die Compilerautoren davon ausgehen, daß die Leute richtige Programme damit schreiben, sparen sie sich solche Prüfungen, weil nur in Spezialfällen davon ausgegangen werden kann, daß wirklich immer das selbe getan wird.

SMO 28. Okt 2005 18:49

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Mh, find ich nun fast enttäuschend. Dann heisst Inlining dort tatsächlich nur Ersparnis des Calls, bzw. der Vorbereitung der Parameter, und den Optimizer kümmerts nicht?

Nein. Jetzt zum dritten Mal: :wall:
Ein "var" Parameter erzwingt eine Speichervariable. Da ist dann nichts mehr drin mit Registeroptimierung und so. Wenn man also solche Tests macht, dann bitte den einzelnen Testfällen (hier der Prozedur und der Funktion) jeweils ihre eigenen lokalen Variablen geben.

Delphi-Quellcode:
var
  i: Integer;
begin
  x(i);
  i := y;
end.
So kann es ja nichts mit der Optimierung werden. Denn erstens ist i hier keine lokale Variable (wird also so oder so auf eine Speicherzelle abgebildet) und zweitens wird i für x und y benutzt, wobei x verhindert, das i auf ein Register statt Speicherzelle abgebildet wird.

So ist es besser:
Delphi-Quellcode:
procedure Test;
var
  ergx, ergy: Integer;
begin
  x(ergx);
  ergy := y;
end;
Mit inlining wird "ergy := y" hier total wegoptimiert. ;)

dizzy 28. Okt 2005 19:29

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von SMO
Zitat:

Zitat von dizzy
Mh, find ich nun fast enttäuschend. Dann heisst Inlining dort tatsächlich nur Ersparnis des Calls, bzw. der Vorbereitung der Parameter, und den Optimizer kümmerts nicht?

Nein. Jetzt zum dritten Mal: :wall:
Ein "var" Parameter erzwingt eine Speichervariable. Da ist dann nichts mehr drin mit Registeroptimierung und so. Wenn man also solche Tests macht, dann bitte den einzelnen Testfällen (hier der Prozedur und der Funktion) jeweils ihre eigenen lokalen Variablen geben.

Um die Variable im Speicher/Register ging es hier garnicht. Es ging um das doppelt ausgeführte xor zum Erzeugen einer Null.

Zitat:

Zitat von SMO
Delphi-Quellcode:
var
  i: Integer;
begin
  x(i);
  i := y;
end.
So kann es ja nichts mit der Optimierung werden. Denn erstens ist i hier keine lokale Variable (wird also so oder so auf eine Speicherzelle abgebildet) und zweitens wird i für x und y benutzt, wobei x verhindert, das i auf ein Register statt Speicherzelle abgebildet wird.

Ist wie gesagt garnicht Gegenstand der Diskussion ;)

Zitat:

Zitat von SMO
So ist es besser:
Delphi-Quellcode:
procedure Test;
var
  ergx, ergy: Integer;
begin
  x(ergx);
  ergy := y;
end;
Mit inlining wird "ergy := y" hier total wegoptimiert. ;)

Das wäre dann aber grober Unfug, es sei denn D2005 tut auf einmal etwas ganz neues: Lokale Variablen mit 0 (nil) initialisieren. Ist dem so? Warum erkennt der Optimizer dann nicht auch, dass in der Prozedur x nur eine Null zugewiesen wird, und optimiert auch diesen Aufruf weg? Sowas meinte ich mit inkonsequent.

Zitat:

Zitat von tommie-lie
Ist es sicherlich, aber es muss implementiert werden. Und da die Compilerautoren davon ausgehen, daß die Leute richtige Programme damit schreiben, sparen sie sich solche Prüfungen, weil nur in Spezialfällen davon ausgegangen werden kann, daß wirklich immer das selbe getan wird.

Wenn ich mich recht entsinne werden Ausdrücke wie "x := sqrt(2)*10;" vom Compiler ausgerechnet und als Konstante implementiert (weiss nicht mehr ob das bei Delphi oder C# der Fall war). Hier könnte man auch argumentieren: Warum rechnet es der Autor nicht selber aus? Kommentieren soll man bei "richtigen" Programmen eh, also kann da auch der Rechenweg dokumentiert sein wenn es um die Lesbarkeit geht =)
Und ich meine es wäre auch (MS)C# gewesen der eine Schleife in der immer nur ein konstanter Wert auf eine Variable addiert wird, im Vorhinein komplett ausrechnet und nur mit einer Konstanten ohne Schleife implementiert. Ein "Optimizer" der nur greift wenn ich eh schon recht optimal gecoded habe, ist imho ebenfalls inkonsequent :). Zumal die Beispiele hier für den Coder offensichtliche Optimierungsmöglichkeiten zeigen. In dem obigen Beispiel geht es eher um die Ebene die der Programmierer erst im asm-code sehen könnte, und somit nichtmal direkten Einfluss darauf hat. Sicher sind die Methoden da oben sehr panne, da sie nur eine 0 schreiben. Aber es geht doch um das Konzept! Wenn so etwas einfaches nicht erkannt/verbessert wird, wie kann ich mich da noch darauf verlassen dass es in komplexeren Zusammenhängen besser läuft?

jbg 28. Okt 2005 20:29

Re: Was ist schneller, Funktion oder Prozedure?
 
Aus den Newsgroups zum Delphi 2005 Optimizer (gilt auch für Delphi 1 bis 7).

SMO 28. Okt 2005 20:37

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Das wäre dann aber grober Unfug, es sei denn D2005 tut auf einmal etwas ganz neues: Lokale Variablen mit 0 (nil) initialisieren. Ist dem so?

Nein. Und das ist kein grober Unfug. Der Compiler erkennt, dass "ergy" im Folgenden gar nicht mehr benutzt wird und auch dass das per inlining eingefügte y nichts tut, was auf den Rest des Programms Auswirkungen haben könnte. Also kann man sowohl den Aufruf von y als auch ergy hier ersatzlos streichen.

Zitat:

Warum erkennt der Optimizer dann nicht auch, dass in der Prozedur x nur eine Null zugewiesen wird, und optimiert auch diesen Aufruf weg? Sowas meinte ich mit inkonsequent.
Inkonsequent ja, aber auf andere Weise als du vielleicht meinst. Wenn man x mit inlining wie in obigem Beispiel aufruft, sollte der Compiler eigentlich auch erkennen, dass der Wert, der hier "ergx" zugewiesen wird, gar nicht benutzt wird, das ganze also wegrationalisiert werden könnte. Ich vermute, da verhindert der var Parameter wieder mal die Optimierung. ;)

Delphi 2005 war die erste Version mit inlining, da kann man noch keine Perfektion erwarten. Ich habe gehört, dass es in Delphi 2006 schon ein bisschen verbessert worden ist.

Flocke 28. Okt 2005 20:43

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Das wäre dann aber grober Unfug, es sei denn D2005 tut auf einmal etwas ganz neues: Lokale Variablen mit 0 (nil) initialisieren. Ist dem so? Warum erkennt der Optimizer dann nicht auch, dass in der Prozedur x nur eine Null zugewiesen wird, und optimiert auch diesen Aufruf weg? Sowas meinte ich mit inkonsequent.

Nicht wenn der Optimizer erkennt, dass ergy danach überhaupt nicht mehr benötigt wird - allerdings sollte er dann eigentlich auch erkennen, dass das für ergx ebenfalls gilt.

Nichtsdestotrotz - Delphi optimiert nicht so, wie es z.B. ein optimierender C- oder C++-Compiler tut. Dieser ist normalerweise auch dafür ausgelegt, total stupiden Code (wie in unserem Beispiel) zu optimieren - wenn sein Input nämlich von anderen Programmen wie lex oder yacc generiert wird, dann kann es sein, dass wirklich 10 mal "x = 10;" untereinander steht.

mael 28. Okt 2005 21:22

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von himitsu
Wobei bei einer Exception sogar ein Var-Parameter seine Vorteile haben kann, da man diesen ja am Anfang der Prozedur (vor einer eventuellen Exception) auf einen bestimmten Wert setzen kann, wärend bei der Funktion im Exceptionfall der Rückgabewert verloren geht.

Der Sinn einer Exception ist gerade zu signalisieren das etwas schief gegangen ist und man eben nicht Rückgabewerte auswerten sollte. Was schief gegangen ist sollte durch den entsprechende Exception-Typ angegeben werden, und eventuell durch eine Fehlermeldung in der exception für den Benutzer präzisiert werden.

tommie-lie 28. Okt 2005 21:52

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Wenn ich mich recht entsinne werden Ausdrücke wie "x := sqrt(2)*10;" vom Compiler ausgerechnet und als Konstante implementiert (weiss nicht mehr ob das bei Delphi oder C# der Fall war).

Berechnungen schreiben sich natürlicher und erhöhen die Übersichtlichkeit, wenn man sie aufsplitten kann und nicht vollständig aufgelöst im Code stehen, zum Beispiel wenn man Datenstrukturen aus Dateien liest, die sich aus mehreren Einzelkomponenten zusammensetzen. Außerdem lässt sich ein einfacher (und der des Delphi-Optimizers ist nur einfach) Matheparser relativ problemlos implementieren. Die Delphi-Hilfe habe ich grad' nicht zur Hand, aber sqrt() müsste Compiler-Magic sein, da ich die Funktion gerade nicht finden kann. Der Aufwand, für die durch Compilermagic implementierten Funktionen eine Auflösung zu schreiben, ist wohl nur gering. Ich schätze, in selbstgeschriebenen Funktionen, die du mit einem konstanten Parameter aufrufst, rechnet er das Ergebnis nicht aus.

Zitat:

Zitat von dizzy
Und ich meine es wäre auch (MS)C# gewesen der eine Schleife in der immer nur ein konstanter Wert auf eine Variable addiert wird, im Vorhinein komplett ausrechnet und nur mit einer Konstanten ohne Schleife implementiert.

Das machen alle gängigen C++-Compiler so, und wenn's der C#-Compiler nicht machen würde, würde's der JIT machen.

Zitat:

Zitat von dizzy
Wenn so etwas einfaches nicht erkannt/verbessert wird, wie kann ich mich da noch darauf verlassen dass es in komplexeren Zusammenhängen besser läuft?

Es ist in komplexen Vorgängen nicht besser ;-)


Edit: Total verquottelt.

dizzy 28. Okt 2005 23:24

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von Flocke
Nicht wenn der Optimizer erkennt, dass ergy danach überhaupt nicht mehr benötigt wird - allerdings sollte er dann eigentlich auch erkennen, dass das für ergx ebenfalls gilt.

@SMO: Genau das war mein Punkt. Und _nur_ das.
Danke Flocke - ich hätts heut irgendwie nicht besser/direkter schreiben können :D

Zitat:

Zitat von Flocke
Nichtsdestotrotz - Delphi optimiert nicht so, wie es z.B. ein optimierender C- oder C++-Compiler tut. Dieser ist normalerweise auch dafür ausgelegt, total stupiden Code (wie in unserem Beispiel) zu optimieren - wenn sein Input nämlich von anderen Programmen wie lex oder yacc generiert wird, dann kann es sein, dass wirklich 10 mal "x = 10;" untereinander steht.

Klingt logisch.

Zitat:

Zitat von tommie-lie
Berechnungen schreiben sich natürlicher und erhöhen die Übersichtlichkeit, wenn man sie aufsplitten kann und nicht vollständig aufgelöst im Code stehen, zum Beispiel wenn man Datenstrukturen aus Dateien liest, die sich aus mehreren Einzelkomponenten zusammensetzen. Außerdem lässt sich ein einfacher (und der des Delphi-Optimizers ist nur einfach) Matheparser relativ problemlos implementieren. Die Delphi-Hilfe habe ich grad' nicht zur Hand, aber sqrt() müsste Compiler-Magic sein, da ich die Funktion gerade nicht finden kann. Der Aufwand, für die durch Compilermagic implementierten Funktionen eine Auflösung zu schreiben, ist wohl nur gering. Ich schätze, in selbstgeschriebenen Funktionen, die du mit einem konstanten Parameter aufrufst, rechnet er das Ergebnis nicht aus.

Oh, um sqrt() gings mir garnicht. Dummes Beispiel... Ich meinte generell einfach, dass konstante Teile einfacher mathematischer Formeln im Vorfeld ausgerechnet werden, und nicht zu Runtime wie es im Code steht. Was die Sache mit der Übersichtlichkeit angeht: Ich bin sogar schon dazu übergegangen tatsächlich konstante Teile einer Formel selber auszurechnen, vor allem wenn dazu eine Umstellung des ursprünglich geschriebenen nötig war, die ich Delphi nicht zutraute. Der Übersicht wegen steht die Ursprungsformel + Rechenweg als Kommentar dabei. Da jeder Code ohnehin kommentiert werden muss... ;). Aber das ist ja garnicht was ich will - eigentlich gehts mir ja darum das Konzept: "Könnte der Coder auch von Hand machen, aber ich tu's wenn er es nicht tut" von eben dieser Optimierung von mathem. Ausdrücken auf die gesamte Optmierung ausgeweitet würde. Das war Sinn und Zweck meiner obigen Aussage :) (Ich muss zugeben - ich drücke mich heut in der Tat nicht überall so eindeutig aus... sorry)

Zitat:

Zitat von tommie-lie
Es ist in komplexen Vorgängen nicht besser ;)

Da gehe ich von aus :D

tommie-lie 29. Okt 2005 08:26

Re: Was ist schneller, Funktion oder Prozedure?
 
Zitat:

Zitat von dizzy
Oh, um sqrt() gings mir garnicht. Dummes Beispiel...

Das dürfte aber so ziemlich der einzige Aufruf sein (ich weiß nicht, was es noch als Compiler-Magic gibt, Sinus und Kosinus und das war's glaub' ich auch schon), den der Compiler direkt zu Compile-Time ausrechnet :zwinker:

Zitat:

Zitat von dizzy
Ich meinte generell einfach, dass konstante Teile einfacher mathematischer Formeln im Vorfeld ausgerechnet werden, und nicht zu Runtime wie es im Code steht.

Wie gesagt, ein mathematischer Parser ist recht einfach, vor allem der von Delphi. So kommt er zum Beispiel nicht damit klar, das konstante und variable Teile gemischt werden, also 2+x+3 kriegt er schonmal nicht hin. Ich weiß nicht, für welche Reihenfolge das gilt, aber wenn die Konstante auf einer bestimmten Seite der Variable ist, kriegt er's auch nicht hin. Also entweder x+2+3 oder 2+3+x wird ebenfalls nicht optimiert, so habe ich es zumindest von Delphi6 in Erinnerung.

Zitat:

Zitat von dizzy
eigentlich gehts mir ja darum das Konzept: "Könnte der Coder auch von Hand machen, aber ich tu's wenn er es nicht tut" von eben dieser Optimierung von mathem. Ausdrücken auf die gesamte Optmierung ausgeweitet würde.

Das ist es, was viele andere Compiler machen. Obiges Beispiel mit der Schleife wäre Loop-Unrolling gewesen, und das kann heute so gut wie jeder bessere Compiler.

Zitat:

Zitat von dizzy
Zitat:

Zitat von tommie-lie
Es ist in komplexen Vorgängen nicht besser ;)

Da gehe ich von aus :D

Da brauchst du nicht von ausgehen, es ist so ;-)


Edit: Irnkwie krieg' ich das mit dem Quoten nicht auf die Reihe...
Edit2: :wall:


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:55 Uhr.

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