arraysdelphidelphi-2009records

Optimizing work with an array of records


I have the following object with an array of a record type:

type
  TTimeMark = record
   // many fields here
  end;

  TTimeMarks = array of TTimeMark;

  TUserProfile = class(TObject)
    TimeLine: TTimeMarks;
    ....
  end;

In this list TUserProfile.TimeLine will be inserted items at run time. I don't know a method of inserting items other than increasing the lenghth of the array with one and then moving all the items a place down until I reach the desired possition. But in this array, the items are records with many fields, so, if I do TimeLine[I]:= TimeLine[I-1], all the data in the memory will be copied from one place to another (am I right ?), and this will take some time. Do you think should I use an array of pointers of that record, instead ? Or is there other fast method to do this ?


Solution

  • This is how I've done.. I used an array of pointers and I make some procedures to easy add, delete and move items:

    TPointerArray = array of Pointer;
    
    procedure PArrayInsert(var AArray: TPointerArray; Position: Integer; Count: Integer = 1);
    var L, CTail: Integer;
    begin
     L:= Length(AArray);
     if (Count = 0) or (Position > L) then Exit;
     SetLength(AArray, L + Count);
     CTail:= L - Position;
     if CTail > 0 then
      Move(AArray[Position], AArray[Position+Count], CTail * SizeOf(Pointer));
    end;
    
    procedure PArrayDelete(var AArray: TPointerArray; Position: Integer; Count: Integer = 1);
    var L, CTail: Integer;
    begin
     L:= Length(AArray);
     if (L = 0) or (Count = 0) or (Position >= L) or ((Position+Count) > L) then Exit;
     CTail:= L - (Position + Count);
     if CTail > 0 then
      Move(AArray[Position+Count], AArray[Position], CTail * SizeOf(Pointer));
     SetLength(AArray, L - Count);
    end;
    
    function PArrayMove(var AArray: TPointerArray; FromIndex, ToIndex: Integer; Count: Integer = 1): Boolean;
    var L, Size, CT: Integer;
        Buff: Pointer;
    begin
     Result:= False;
     L:= High(AArray);
     if (FromIndex > L) or (ToIndex > L+1) or
      ((ToIndex >= FromIndex) and (ToIndex <= (FromIndex+Count)))  then Exit;
     Size:= Count * SizeOf(Pointer);
     GetMem(Buff, Size);
     Move(AArray[FromIndex], Buff^, Size);
     if FromIndex > ToIndex then begin
      CT:= FromIndex - ToIndex;
      Move(AArray[ToIndex], AArray[FromIndex+Count-CT], CT * SizeOf(Pointer));
      Move(Buff^, AArray[ToIndex], Size);
     end
     else begin
      CT:= ToIndex - FromIndex - Count;
      Move(AArray[FromIndex+Count], AArray[FromIndex], CT * SizeOf(Pointer));
      Move(Buff^, AArray[FromIndex+CT], Size);
     end;
     FreeMem(Buff);
     Result:= True;
    end;