![]() |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Delphi-Quellcode:
(
const [Ref]
![]() ![]() |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Grund: Durch das Create selbst wird logischerweise der Referenzzähler nicht erhöht, durch das const ist aber auch die Referenzzählung für den Parameter deaktiviert. Also steht der Referenzzähler auf 0. Übergibt nun der Konstruktor das Interface an eine weitere Routine mit Referenzzählung, wird die Referenz um 1 erhöht und wieder auf 0 gesetzt. Danach ist dann die Referenz ungültig. Solange man sauber immer mit Zwischenvariablen arbeitet, ist aber alles in Ordnung. So einen Fehler findet man aber leider nicht unbedingt so schnell... |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Mavarik |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Delphi-Quellcode:
wie CallByValue:
const
Delphi-Quellcode:
Bei komplexen Datentypen (Objekte, Records, Interfaces, Strings) dahingegen wie CallByReference (dann wird allerdings auch der Parameter, welcher komplett ohne
Unit1.pas.45: A(X);
005CDEEF 8B45F8 mov eax,[ebp-$08] // CallByValue 005CDEF2 E8D9FFFFFF call A // procedure A(X: Integer) Unit1.pas.46: B(X); 005CDEF7 8D45F8 lea eax,[ebp-$08] // CallByReference 005CDEFA E8D5FFFFFF call B // procedure B(var X: Integer) Unit1.pas.47: C(X); 005CDEFF 8B45F8 mov eax,[ebp-$08] // CallByValue 005CDF02 E8D1FFFFFF call C // procedure C(const X: Integer)
Delphi-Quellcode:
oder
const
Delphi-Quellcode:
deklariert wurde als CallByReference umgesetzt. Der einzige Unterschied zwischen
var
Delphi-Quellcode:
und "nichts" besteht hier wirklich nur in der Schreibschutzprüfung - welche wie du bereits vermutet hast - zur Compiletime umgesetzt wird):
const
Delphi-Quellcode:
Hierbei ist Delphi sogar so klug, Records mit z.b. nur einem einzigen Integer Element trotzdem als trivialen Datentyp zu behandeln.
Unit1.pas.52: A(X);
005CDEEF 8D45F4 lea eax,[ebp-$0c] // CallByReference 005CDEF2 E8D9FFFFFF call A // procedure A(X: TStruct) Unit1.pas.53: B(X); 005CDEF7 8D45F4 lea eax,[ebp-$0c] // CallByReference 005CDEFA E8D5FFFFFF call B // procedure B(var X: TStruct) Unit1.pas.54: C(X); 005CDEFF 8D45F4 lea eax,[ebp-$0c] // CallByReference 005CDF02 E8D1FFFFFF call C // procedure C(const X: TStruct) Die eigentliche Optimierung sieht man im Falle des Structs hier ganz schön (jeweils komplett leere Funktionen):
Delphi-Quellcode:
Und bei Strings sieht die Sache ähnlich aus (ebenfalls jeweils komplett leere Funktionen):
// procedure A(X: TStruct)
Unit1.pas.32: begin 005CDED0 55 push ebp 005CDED1 8BEC mov ebp,esp 005CDED3 81C46CFEFFFF add esp,$fffffe6c 005CDED9 56 push esi 005CDEDA 57 push edi 005CDEDB 8BF0 mov esi,eax 005CDEDD 8DBD6CFEFFFF lea edi,[ebp-$00000194] 005CDEE3 B965000000 mov ecx,$00000065 005CDEE8 F3A5 rep movsd Unit1.pas.34: end; 005CDEEA 5F pop edi 005CDEEB 5E pop esi 005CDEEC 8BE5 mov esp,ebp 005CDEEE 5D pop ebp 005CDEEF C3 ret // procedure B(var X: TStruct) Unit1.pas.37: begin 005CDEF0 55 push ebp 005CDEF1 8BEC mov ebp,esp 005CDEF3 51 push ecx 005CDEF4 8945FC mov [ebp-$04],eax Unit1.pas.39: end; 005CDEF7 59 pop ecx 005CDEF8 5D pop ebp 005CDEF9 C3 ret // procedure C(const X: TStruct) Unit1.pas.42: begin 005CDEFC 55 push ebp 005CDEFD 8BEC mov ebp,esp 005CDEFF 51 push ecx 005CDF00 8945FC mov [ebp-$04],eax Unit1.pas.44: end; 005CDF03 59 pop ecx 005CDF04 5D pop ebp 005CDF05 C3 ret
Delphi-Quellcode:
// procedure A(X: String)
Unit1.pas.32: begin 005CDED0 55 push ebp 005CDED1 8BEC mov ebp,esp 005CDED3 51 push ecx 005CDED4 8945FC mov [ebp-$04],eax 005CDED7 8B45FC mov eax,[ebp-$04] 005CDEDA E881BEE3FF call @UStrAddRef 005CDEDF 33C0 xor eax,eax 005CDEE1 55 push ebp 005CDEE2 6803DF5C00 push $005cdf03 005CDEE7 64FF30 push dword ptr fs:[eax] 005CDEEA 648920 mov fs:[eax],esp Unit1.pas.34: end; 005CDEED 33C0 xor eax,eax 005CDEEF 5A pop edx 005CDEF0 59 pop ecx 005CDEF1 59 pop ecx 005CDEF2 648910 mov fs:[eax],edx 005CDEF5 680ADF5C00 push $005cdf0a 005CDEFA 8D45FC lea eax,[ebp-$04] 005CDEFD E87ABDE3FF call @UStrClr 005CDF02 C3 ret 005CDF03 E990B3E3FF jmp @HandleFinally 005CDF08 EBF0 jmp $005cdefa 005CDF0A 59 pop ecx 005CDF0B 5D pop ebp 005CDF0C C3 ret // procedure B(var X: String) Unit1.pas.37: begin 005CDF10 55 push ebp 005CDF11 8BEC mov ebp,esp 005CDF13 51 push ecx 005CDF14 8945FC mov [ebp-$04],eax Unit1.pas.39: end; 005CDF17 59 pop ecx 005CDF18 5D pop ebp 005CDF19 C3 ret // procedure C(const X: String) Unit1.pas.42: begin 005CDF1C 55 push ebp 005CDF1D 8BEC mov ebp,esp 005CDF1F 51 push ecx 005CDF20 8945FC mov [ebp-$04],eax Unit1.pas.44: end; 005CDF23 59 pop ecx 005CDF24 5D pop ebp 005CDF25 C3 ret |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
|
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
|
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Das mit der Beschreibbarkeit ist auch korrekt. Das passiert komplett zur Compiletime - sowohl für CallByValue, als auch für CallByReference. |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
|
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Und nein, denn wenn das schon zu Beginn 1 ist und man übergibt das Interface an eine Variable, dann wäre es danach 2. Ist die Variable dann weg, wäre es aber immernoch 1 und würde niemals freigegeben. |
AW: Code Optimisation: Benutzung von const in prozedur-Köpfen
Zitat:
Ich habe in C schon manuelle Referenzzählung implementiert und dort habe ich es immer so gemacht:
Code:
So sollte es der Compiler auch machen.
typedef struct RefCounted {
int refcount; } RefCounted; RefCounted* refcounted_new() { RefCounted *obj = malloc(sizeof(RefCounted)); obj->refcount = 1; return obj; } void refcounted_destroy(RefCounted *obj) { free(obj); } void addref(RefCounted *obj) { ++(obj->refcount); } void release(RefCounted *obj) { --(obj->refcount); if (obj->refcount==0) { refcounted_destroy(obj); } } int main() { RefCounted *obj = refcounted_new(); // Hier KEIN addref(obj) blablabla_irgendwas_mit_obj_machen(obj); release(obj); } |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:48 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