Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - TList durchzählen
Bergmann89 - Do 03.09.09 13:26
Titel: TList durchzählen
HI,
ich bin grad dabei n Geschwindigkeitstest zwischen Array, TList und ner doppelt verketteten Liste von mir zu machen. Und ich hab n par Probleme bei der TList. Wenn ich auf die Items mit List.Item[index] zugreif dauert es sehr lang. Ich such sowas wie List.GetNext gibts das bei den Listen nich, oder funzt das hier bloß bisl anders?
MfG & Thx Bergmann.
Gausi - Do 03.09.09 13:53
TList ist intern ein Array. Der Zugriff auf aList[aIndex] geht da prinzipiell genauso schnell wie bei einem Array. Deshalb gibt es kein TList.GetNext - man nimmt einfach den nächsthöheren Index.
Dude566 - Do 03.09.09 14:56
Müsste doch mit einer Schleife in der du den Index höchzählst recht schnell gehen solange es nicht zu große Datenmengen sind.
Bergmann89 - Do 03.09.09 17:03
Hey,
es is bedeutend langsamer als ein normales Array:
OnCreate:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| List := TList.Create; for i := 0 to 99 do begin Arr[i] := i; List.Add(PInteger(i)); end; |
Liste durchzählen (ca. 1600ms):
Delphi-Quelltext
1: 2: 3: 4: 5:
| StartTime := GetTickCount; for j := 0 to 1000000 do for i := 0 to 99 do List[i] := PInteger(Integer(List[i]) + 1); Button3.Caption := IntToStr(GetTickCount - StartTime); |
Array durchzählen(ca. 160ms):
Delphi-Quelltext
1: 2: 3: 4: 5:
| StartTime := GetTickCount; for j := 0 to 1000000 do for i := 0 to 99 do Arr[i] := Arr[i] + 1; Button2.Caption := IntToStr(GetTickCount - StartTime); |
da ich das Ganze für ein Spiel verwenden will, is die Performance extrem wichtig...
MfG Bergmann.
Gausi - Do 03.09.09 17:11
Ich würde vermuten, dass bei TList die ganzen Casts und andere interne Dinge die Laufzeit zerhauen. Daher auch das "prinzipiell" in meiner vorigen Aussage. Kann gut sein, dass da ein Faktor 10 durch diesen Kram reinkommt - im O-Kalkül ist das wurscht. ;-)
Bergmann89 - Do 03.09.09 17:21
Im O-Kalkül vieleicht, aber nich bei den FPS meines Spiels ^^
Tilman - Do 03.09.09 17:36
Du darfst beim Initialisieren den Wert nicht in einen PInteger wandeln, weil der Zeiger nach ablauf der Lokalen Prozedur weg ist (okay war nur ein Test, aber Normalerweise geht das nicht so deswegen sag ichs hier, man muss erst Speicher mit New oder GetMem besorgen).
So haben beide Prozeduren bei mir dieselbe Performance:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TForm1.Button1Click(Sender: TObject); var zahl: pInteger; begin StartTime := GetTickCount; for j := 0 to 1000000 do for i := 0 to 99 do begin zahl := list[i]; inc(zahl^); end; label1.Caption := IntToStr(GetTickCount - StartTime); end;
procedure TForm1.Button3Click(Sender: TObject); var zahl: pInteger; begin List := TList.Create; for i := 0 to 99 do begin Arr[i] := i; new(zahl); zahl^ := i; List.Add(zahl); end; end;
procedure TForm1.Button2Click(Sender: TObject); begin StartTime := GetTickCount; for j := 0 to 1000000 do for i := 0 to 99 do Arr[i] := Arr[i] + 1; label1.Caption := IntToStr(GetTickCount - StartTime); end; |
Dude566 - Do 03.09.09 18:08
Was steht denn in StartTime, die Uhrzeit wo es gestartet wird oder ist das ein Startwert der auf Null steht?
Xentar - Do 03.09.09 18:18
Dude566 hat folgendes geschrieben : |
Was steht denn in StartTime, die Uhrzeit wo es gestartet wird oder ist das ein Startwert der auf Null steht? |
Steht doch im Quellcode, wo der Wert gesetzt wird :roll:
GetTickCount, also Zeit in ms seit Systemstart.
Bergmann89 - Do 03.09.09 22:02
Hey,
@Tilman: bei mir sind die Zeien nich gleich. Hab aber alles genau so wie du:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
| procedure TForm1.FormCreate(Sender: TObject); var i: Integer; var Zahl: PInteger; [...] begin [...] List := TList.Create; for i := 0 to 99 do begin new(Zahl); zahl^ := i; Arr[i] := zahl;
new(zahl); zahl^ := i; List.Add(Zahl);
[...] end; end;
procedure TForm1.Button1Click(Sender: TObject); var StartTime: Cardinal; var i,j: Integer; begin StartTime := GetTickCount; for j := 0 to 1000000 do for i := 0 to 99 do Arr[i]^ := Arr[i]^ + 1; Button1.Caption := IntToStr(GetTickCount-StartTime); end;
procedure TForm1.Button2Click(Sender: TObject); var StartTime: Cardinal; var i,j: Integer; begin StartTime := GetTickCount; for j := 0 to 1000000 do for i := 0 to 99 do inc(PInteger(List[i])^);
Button2.Caption := IntToStr(GetTickCount-StartTime); end; |
un dann hab ich ma noch ne SingleLinkedList implementiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| TListItem = class(TObject) p: Pointer; NextItem: TListItem; end;
procedure TForm1.FormCreate(Sender: TObject); [...] var Zahl: PInteger; var tmp: TListItem; begin FirstItem := TListItem.Create; tmp := FirstItem; [...] for i := 0 to 99 do begin [...] new(zahl); zahl^ := i; tmp.p := Zahl; if i <> 99 then begin tmp.NextItem := TListItem.Create; tmp := tmp.NextItem; end; end; end;
procedure TForm1.Button4Click(Sender: TObject); var tmp: TListItem; var i: Integer; var StartTime: Cardinal; begin StartTime := GetTickCount; for i := 0 to 1000000 do begin tmp := FirstItem; while Assigned(tmp.NextItem) do begin inc(PInteger(tmp.p)^); tmp := tmp.NextItem; end; inc(PInteger(tmp.p)^); end; Button4.Caption := IntToStr(GetTickCount-StartTime); end; |
Ich denk ma das is die beste Lösung. Das is ganz einfach gehalten, is schneller als die TList und ich kann auch sehr gut Elemente hinzufügen und löschen. Das is das, was ich für mein Spiel brauch. Also werd ich das dann wohl so umsetzten...
Mfg Bergmann.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!