Generic-Listen mit großen Records sind sehr ungünstig, da sie eigentlich nur mit Kopieren der Records beschäftigt sind.
Delphi-Quellcode:
if (Self.Items[i].First) then // 1x Kopieren in vom Compiler eingefügte lokale Record-Variable um auf First zuzugreifen
begin
tmpData := Self.Items[i]; // 1x Kopieren in lokale Record-Variable
Self.Delete(i); // Kopieren aller nachfolgenden Records im Array der Liste um eins nach vorne.
aFirstList.Add(tmpData); // 1x Kopieren in das Array der Liste.
end
Das ganze wäre um einiges schneller, wenn du statt dem Record einen Zeiger auf den Record nutzt. Dann besteht das Kopieren nur aus 4 Bytes statt aus den 2732 Bytes mit Managed Datentypen (String). Um das Anlegen und die Freigabe der Items musst du dich dann natürlich selbst kümmern.
Das würde dann so aussehen: (mit automatischer Freigabe wenn Delete/Clear aufgerufen wird.
Delphi-Quellcode:
type
PMyData = ^TMyData;
TMyData = record ... end;
TMyListe = class(TList<PMyData>)
protected
procedure Notify(const Item: PMyData; Action: TCollectionNotification); override;
function GetFirstItems(aFirstList: TMyListe): Integer;
end;
{ TMyDataList }
procedure TMyListe.Notify(const Item: PMyData; Action: TCollectionNotification);
begin
inherited Notify(Item, Action);
if Action = cnRemoved then
Dispose(Item);
end;
function TMyListe.GetFirstItems(aFirstList: TMyListe): Integer;
var
i: Integer;
tmpData: PMyData;
begin
if Assigned(aFirstList) then
begin
aFirstList.Clear;
i := 0;
while i < Self.Count do
begin
if (Self.Items[i].First) then
begin
tmpData := Self.Extract(Self.Items[i]);
aFirstList.Add(tmpData);
end
else begin
inc(i);
end;
end;
end;
Result := aFirstList.Count; // was wenn aFirstList=nil ist?
end;
...
var
aData: PMyData;
begin
...
for i := 1 to 5000 do
begin
//New(aData); // Neuen Record im Speicher anlegen
//aData.Clear;
aData := AllocMem(SizeOf(TMyData)); // etwas schneller als New+FillChar, da New zusätzlich noch die Managed-Typen auf nil/Leerstring setzt, was FillChar dann gleich nochmal macht.
aData.ID := i;
aData.First := True;
AllDataList.Add(aData); // Owner ist nun AllDataList
end;