![]() |
VAR CONST OUT und Co. ... warum?
da es ja immer öfters mal vorkommt, daß gefragt wird warum es oftmals besser ist ein CONST anzugeben
Zitat:
![]() Da die Meisten eh nicht sehen, was hinter den Kulissen alles von Delphi wann gemacht wird, hab ich es einfach mal über eine Laufzeitmessung dargestellt (je mehr gemacht wird, umso länger dauert es ja bekanntlich :nerd: ) Es wäre es schwer hier alles aufzuzeigen, was wann gemacht wird, da es von den Datentypen und auch noch von der Aufrufkonvention abhängig ist, was wie wo gemacht wird ... außerdem ist es ja nur wichtig zuwissen daß etwas gemacht wird und das wie ist hierbei mal völlig egal. :roll: hier ein kleiner Testcode, welcher - ein wirklich großes 10-MB-Array - einen String - einen Record - und 'nen Int64 (auch wenn da die Aufrufconvention eigenartig ist :? ) testet.
Delphi-Quellcode:
raus kommt dann z.B. sowas (D7)
{$MAXSTACKSIZE 25000000} // ist sonst nur 1 MB
// und das 10-MB-Array muß ja dort 2-mal reinpassen (doppelt, für die Kopie ohne Const/Var) Type TArray = Array[1..10*1024*1024] of Byte; TDynArray = Array of Byte; Procedure TestProcA(Arr: TArray); Begin If Arr[2] = 2 Then ; End; Procedure TestProcAC(Const Arr: TArray); Begin If Arr[2] = 2 Then ; End; Procedure TestProcAV(Var Arr: TArray); Begin If Arr[2] = 2 Then ; End; Procedure TestProcD(Arr: TDynArray); Begin If Arr[2] = 2 Then ; End; Procedure TestProcDC(Const Arr: TDynArray); Begin If Arr[2] = 2 Then ; End; Procedure TestProcDV(Var Arr: TDynArray); Begin If Arr[2] = 2 Then ; End; Procedure TestProcS(S: String); Begin If S = '' Then ; End; Procedure TestProcSC(Const S: String); Begin If S = '' Then ; End; Procedure TestProcR(R: TRect); Begin If R.Left = 0 Then ; End; Procedure TestProcRC(Const R: TRect); Begin If R.Left = 0 Then ; End; // Integer drin, damit der der Int64 nicht in den Registern landet (AntiParameterOptimierung) Procedure TestProcI(i: Integer; i2: UInt64); Begin If i2 = 0 Then ; End; // irgendwie bin ich grad zu blöd und Int64 wir dennoch in die Register/den Stack geladen Procedure TestProcIC(i: Integer; {Const}Var i2: UInt64); Begin If i2 = 0 Then ; End; Procedure TForm1.Button1Click(Sender: TObject); Var Ts, Te: Int64; Arr: TArray; DynArr: TDynArray; S: String; R: TRect; F: Double; i2: UInt64; i: Integer; C: LongWord; Begin Memo1.Lines.Clear; Memo1.Font.Name := 'Courier New'; C := GetTickCount; // CPU hochfahren, falls sie dynamisch getaktet ist QueryPerformanceCounter(Ts); For i := 0 to 500000000 do i2 := i; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('spin up: %11.0n ticks', [(Te - Ts) / 1])); Memo1.Lines.Add(''); QueryPerformanceCounter(Ts); For i := 0 to 1000 do Begin Arr[2] := i; TestProcA(Arr); End; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('Array: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 1000 do Begin Arr[2] := i; TestProcAC(Arr); End; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('Array-Const: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 1000 do Begin Arr[2] := i; TestProcAV(Arr); End; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('Array-Var: %11.0n ticks', [(Te - Ts) / 1])); Memo1.Lines.Add(''); SetLength(DynArr, 10*1024*1024); QueryPerformanceCounter(Ts); For i := 0 to 1000 do Begin DynArr[2] := i; TestProcD(DynArr); End; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('DynArray: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 1000 do Begin DynArr[2] := i; TestProcDC(DynArr); End; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('DynArray-Const: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 1000 do Begin DynArr[2] := i; TestProcDV(DynArr); End; QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('DynArray-Var: %11.0n ticks', [(Te - Ts) / 1])); Memo1.Lines.Add(''); QueryPerformanceCounter(Ts); For i := 0 to 100000 do TestProcS(S); QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('String: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 100000 do TestProcSC(S); QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('String-Const: %11.0n ticks', [(Te - Ts) / 1])); Memo1.Lines.Add(''); QueryPerformanceCounter(Ts); For i := 0 to 100000 do TestProcR(R); QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('TRect: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 100000 do TestProcRC(R); QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('TRect-Const: %11.0n ticks', [(Te - Ts) / 1])); Memo1.Lines.Add(''); QueryPerformanceCounter(Ts); For i := 0 to 200000 do TestProcI(i, i2); QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('Int64: %11.0n ticks', [(Te - Ts) / 1])); QueryPerformanceCounter(Ts); For i := 0 to 200000 do TestProcIC(i, i2); QueryPerformanceCounter(Te); Memo1.Lines.Add(Format('Int64-{Const}Var: %11.0n ticks', [(Te - Ts) / 1])); Memo1.Lines.Add(''); Memo1.Lines.Add(Format('end (%n sec)', [(GetTickCount - C) / 1000])); End;
Code:
[edits] was man noch so alles anders machen kann :shock:
spin up: 2.259.813 ticks
Array: 27.141.695 ticks Array-Const: 13 ticks Array-Var: 16 ticks DynArray: 117 ticks DynArray-Const: 16 ticks DynArray-Var: 16 ticks String: 12.047 ticks String-Const: 932 ticks TRect: 2.387 ticks TRect-Const: 799 ticks Int64: 2.188 ticks Int64-{Const}Var: 1.879 ticks end (8,24 sec) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:35 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