使用记录数组优化工作
Optimizing work with an array of records
我有以下带有记录类型数组的对象:
type
TTimeMark = record
// many fields here
end;
TTimeMarks = array of TTimeMark;
TUserProfile = class(TObject)
TimeLine: TTimeMarks;
....
end;
在此列表中 TUserProfile.TimeLine
将在 运行 时插入项目。除了用一个增加数组的长度然后将所有项目向下移动一个位置直到我到达所需的位置之外,我不知道插入项目的方法。但是在这个数组中,项目是有很多字段的记录,所以,如果我这样做 TimeLine[I]:= TimeLine[I-1]
,内存中的所有数据都会从一个地方复制到另一个地方(我说的对吗?),这将花费一些时间时间。你认为我应该使用该记录的指针数组吗?或者有其他快速方法可以做到这一点吗?
我就是这样做的。我使用了一个指针数组,并编写了一些程序来轻松添加、删除和移动项目:
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;
我有以下带有记录类型数组的对象:
type
TTimeMark = record
// many fields here
end;
TTimeMarks = array of TTimeMark;
TUserProfile = class(TObject)
TimeLine: TTimeMarks;
....
end;
在此列表中 TUserProfile.TimeLine
将在 运行 时插入项目。除了用一个增加数组的长度然后将所有项目向下移动一个位置直到我到达所需的位置之外,我不知道插入项目的方法。但是在这个数组中,项目是有很多字段的记录,所以,如果我这样做 TimeLine[I]:= TimeLine[I-1]
,内存中的所有数据都会从一个地方复制到另一个地方(我说的对吗?),这将花费一些时间时间。你认为我应该使用该记录的指针数组吗?或者有其他快速方法可以做到这一点吗?
我就是这样做的。我使用了一个指针数组,并编写了一些程序来轻松添加、删除和移动项目:
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;