|
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.229 Beiträge Delphi 12 Athens |
#1
da es ja immer öfters mal vorkommt, daß gefragt wird warum es oftmals besser ist ein CONST anzugeben
Zitat von himitsu:
wenn die Variablen eh nicht verändert werden sollen, wozu sie veränderbar machen?
(also Prozedurintern) gut, bei Strings gibt es die Referenzzählung, aber nicht immer (vorallem nicht bei WideString) und bei Records und auch allem über 32 Bit wird ohne das Const erst eine Kopie des Parameters angelegt, worin die Prozeduinternen änderungen stattfinden können. übergib mal z.B. ein rießiges Static-Array, einen großen Record oder einen langen WideString ... diese müssen erst kopiert und am Ende wieder freigegeben werden. und auch bei kleinen Strukturen müßte das erst von Delphi gemacht werden, selbst wenn es unnötig wäre. CONST (könnte man auch als IN), VAR, OUT und (nichts) gibt es ja nicht umsonst zur Auswahl und Const bzw. Var wird bei "größeren" Strukturen dann einfach als Zeiger auf die Originaldaten umgesetzt und läuft nicht über 'ne "Kopie". (kleine Ausnahmen bilden Objekte, welche "nur" Zeiger sind, sowie Strings bzw. DynArrays, welche eine Referenzzählung besitzen) 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 ) 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. 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
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)
$2B or not $2B
|
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |