Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Function/Procedure -Deklaration ?! (https://www.delphipraxis.net/20535-function-procedure-deklaration.html)

Matze 20. Apr 2004 11:42

Re: Function/Procedure -Deklaration ?!
 
Wenn du das var voranstellst, dann wird einfach die Speicheradresse überschreiben, das braucht natürlich nicht mehr Speicher, aber ohne das var wird ja eine Kopie der Variable angelegt, somit sollte das dann etwas mehr Speicherplatz verbrauchen.

Das mit den 4 Bytes stimmt, wenn man const und var betrachtet, aber ohne diese beiden müsste es theoretisch doch mehr verbrauchen. :gruebel:

Oder nicht?

Muetze1 20. Apr 2004 13:06

Re: Function/Procedure -Deklaration ?!
 
Moin!

Zitat:

Zitat von Matze
..., aber ohne das var wird ja eine Kopie der Variable angelegt, ...

Bei Const doch grundlegend auch, wenn die Variable eine Grösse > 4 Bytes hat.

MfG
Muetze1

maximov 20. Apr 2004 13:24

Re: Function/Procedure -Deklaration ?!
 
Zitat:

Zitat von Muetze1
Moin!

Zitat:

Zitat von Matze
..., aber ohne das var wird ja eine Kopie der Variable angelegt, ...

Bei Const doch grundlegend auch, wenn die Variable eine Grösse > 4 Bytes hat.

MfG
Muetze1

Nö, warum denn? Hauptsache der wert kommt an und das tut er auch per reference. Das er read-only ist, darum kümmert sich lediglich der compiler, der dann nämlich aussteigt.

Übrigens kann man const-paras deshalb sehr wohl beschreiben, wenn man bischen mit ^ und @ rumspielt:

Delphi-Quellcode:
type
  pPoint = ^TPoint;

procedure Foo(const bar:TPoint);
begin
   pPoint(@bar)^ := Point(10,20);
end;


procedure TForm1.Button1Click(Sender: TObject);
var c:TPoint;
begin
  c := Point(0,0);
  foo(c);
  ShowMessage(intToStr(c.X)+','+intToStr(c.Y));
end;
Allerdings nur bei werten > 4 byte...oder so!

sonic 20. Apr 2004 15:00

Re: Function/Procedure -Deklaration ?!
 
Hallo Leute

Habe eure Diskussion verfolgt. Folgendes macht Delphi bei den Übergabeattributen:

Fall 1:
Code:
procedure Test(a: string) -> call by value
Fall 2:
Code:
procedure Test(const a: string) -> call by reference
Fall 3:
Code:
procedure Test(var a: string) -> call by reference
Beim Fall 1 wird der String als "call by Value" übergeben. Da es sich hierbei um einen string = (Objekt) handelt, sind einige Maschinencodeanweisungen notwendig. Wenn man im FPU-Debugger die erzeugten Anweisungen ansieht, kommen dabei um die 30 Assembleranweisungen zusammen.

Beim Fall 2 und 3 wird der String als "call by reference" übergeben. Dabei handelt es sich nur mehr um die Speicheradresse der Variablen (4 Byte), die über den Stack übergeben wird. Dafür ist nur mehr eine Maschinencodeanweisung notwendig. Geschwindigkeitsmäßig sollten Fall 2 und Fall 3 gleich schnell sein.

(Informationen stammen von meinem Persönlichen Delphi Lehrer)

Mfg Mike.

PS. Habe mich also geirrt, Const ist schneller als ohne was, aber nicht schneller als var... :wall:

Muetze1 20. Apr 2004 15:34

Re: Function/Procedure -Deklaration ?!
 
Moin!

Ok, ich habe das ganze jetzt nochmal debuggt und folgendes kam dabei raus: alle 3 Formen haben ein und die selbe Übergabeform:

EAX = Self der Form
EDX = Zeiger auf den String

Die Funktionen sind alle gleich vom Aufruf her - was durch den Variablentyp mit einer Grösse > 4 auch kein Wunder ist - vor allem wird bei Strings so oder so nur mit einer Instanzenaddresse gearbeitet.

Code:
  push ebp
  mov ebp, esp
  add esp, -$08  // Platz für 2x 4 Byte machen - sichern der Var's
  mov [ebp-$08], edx // String sichern auf'm Stack
  mov [ebp-$04], eax // Instanzenzeiger sichern auf'm Stack
 
  // hier ist ein Unterschied - siehe unten

  mov edx, [ebp-$08] // String holen
  mov eax, [ebp-$04] // Instanzenzeiger holen
  call Trim

...
Der Unterschied besteht bei der 1. Funktion wo kein Const und kein Var angeben wurde, dort wird vor dem Aufruf von Trim() sicher gestellt, dass es keine anderen Referenzen auf den String gibt - also wird, wenn eine Referenz da ist, diese abgespalten in einen eigenen String. Danach wird der eindeutige String nach dem Trim gelöscht - also Referenz entfernen und String löschen. Mit anderen Worten: Bei der ersten Form wird vorher keine Kopie von dem String gemacht, das macht die Funktion selber, wenn nötig - also wenn es mehr als eine Referenz auf den String gibt.

Mein Testcode dazu (Optimierung aus, sonst kann man das nicht so schön sehen)
Code:
Function Test1(AStr : String): String;
Begin
  Result := Trim(AStr);
End;

Function Test2(Const AStr : String): String;
Begin
  Result := Trim(AStr);
End;

Function Test3(Var AStr : String): String;
Begin
  Result := Trim(AStr);
End;

procedure TForm1.FormCreate(Sender: TObject);
Var
  s : String;
begin
  s := Edit1.Text;

  Label1.Caption := Test1(s);
  Label2.Caption := Test2(s);
  Label3.Caption := Test3(s);
end;
Zusammenfassung:

Die Aufrufart ohne Const oder Var sorgt für grösseren Code für die Duplizierung / Dereferenzierung. Die anderen beiden Arten sind völlig gleich. Und wohl gemerkt ist trotz des Unterschiedes kein Unterschied zwischen der by value oder by reference Übergabe zu sehen, weil die Übergabe der Parameter geschieht komplett gleich - die by reference Geschichte wird von der Funktion selber sicher gestellt.

MfG
Muetze1

Matze 20. Apr 2004 17:01

Re: Function/Procedure -Deklaration ?!
 
Danke, dass du dir die Mühe gemacht hast, find ich echt klasse! :thumb:

Nur verstehe ich's immer noch nicht genau. :-?
Ist zwar Off-Topic, aber auch net so ganz. ;)

NicoDE 20. Apr 2004 17:14

Re: Function/Procedure -Deklaration ?!
 
Zitat:

Zitat von Muetze1
Die Aufrufart ohne Const oder Var sorgt für grösseren Code für die Duplizierung / Dereferenzierung. Die anderen beiden Arten sind völlig gleich. Und wohl gemerkt ist trotz des Unterschiedes kein Unterschied zwischen der by value oder by reference Übergabe zu sehen, weil die Übergabe der Parameter geschieht komplett gleich - die by reference Geschichte wird von der Funktion selber sicher gestellt.

Nur mal so als Anregung: mach das mal mit ShortString (bzw. anderen Strukturen ohne integrierten Referenzzähler).

Muetze1 20. Apr 2004 20:58

Re: Function/Procedure -Deklaration ?!
 
Moin!

Mir ist ja wirklich schlecht geworden, als ich das mal mit einem ShortString gemacht habe...

Die Ergebnisse:

1. Ohne Var oder Const packt er den kompletten ShortString auf den Stack! (also wenn das keine Verschwendung ist, aber wir haben's ja unter Windows)
2. Mit einem Const das gleiche, nur da ist es fast noch schlimmer: die Funktion kopiert sich von dem ShortString, der auch hier komplett auf dem Stack liegt, eine Kopie in die Stackframe. Mit anderen Worten der Stack in der Funktion sieht dann so aus, dass er einmal den kompletten ShortString als Param liegen hat auf'm Stack beim Eintritt. Dann besorgt er sich nochmal 256 Bytes Platz auf dem Stack (ESP verschieben) und kopiert in den neuen Platz den String von weiter vorne. Dann nutzt er bei den weiteren Funktionen die Kopie.
3. Die Var - Variante bekommt eine Referenz / Zeiger auf den String übergeben.

Fazit: Nur die Var Methode dürfte in so fern schneller sein und vor allem Stack-freundlicher.
Abhilfe: keinen ShortString verwenden, sondern einen AnsiString/String, der kann Referenzen....

MfG
Muetze1


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:49 Uhr.
Seite 3 von 3     123   

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