Delphi-PRAXiS
Seite 2 von 4     12 34      

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)

bigg 28. Okt 2005 15: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 15: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 15: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 15: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 16: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 16: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 16: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 16: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 16: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 16: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:


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:15 Uhr.
Seite 2 von 4     12 34      

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