mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-07-18 14:15:58 +02:00
* Fix bug #0036270: optimize TFPSList.AddList and .Assign
git-svn-id: trunk@43473 -
This commit is contained in:
parent
3238a07a54
commit
d21a262a6c
@ -41,6 +41,8 @@ type
|
|||||||
TFPSList = class;
|
TFPSList = class;
|
||||||
TFPSListCompareFunc = function(Key1, Key2: Pointer): Integer of object;
|
TFPSListCompareFunc = function(Key1, Key2: Pointer): Integer of object;
|
||||||
|
|
||||||
|
{ TFPSList }
|
||||||
|
|
||||||
TFPSList = class(TObject)
|
TFPSList = class(TObject)
|
||||||
protected
|
protected
|
||||||
FList: PByte;
|
FList: PByte;
|
||||||
@ -48,6 +50,7 @@ type
|
|||||||
FCapacity: Integer; { list has room for capacity+1 items, contains room for a temporary item }
|
FCapacity: Integer; { list has room for capacity+1 items, contains room for a temporary item }
|
||||||
FItemSize: Integer;
|
FItemSize: Integer;
|
||||||
procedure CopyItem(Src, Dest: Pointer); virtual;
|
procedure CopyItem(Src, Dest: Pointer); virtual;
|
||||||
|
procedure CopyItems(Src, Dest: Pointer; aCount : Integer); virtual;
|
||||||
procedure Deref(Item: Pointer); virtual; overload;
|
procedure Deref(Item: Pointer); virtual; overload;
|
||||||
procedure Deref(FromIndex, ToIndex: Integer); overload;
|
procedure Deref(FromIndex, ToIndex: Integer); overload;
|
||||||
function Get(Index: Integer): Pointer;
|
function Get(Index: Integer): Pointer;
|
||||||
@ -68,6 +71,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(AItemSize: Integer = sizeof(Pointer));
|
constructor Create(AItemSize: Integer = sizeof(Pointer));
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
class Function ItemIsManaged : Boolean; virtual;
|
||||||
function Add(Item: Pointer): Integer;
|
function Add(Item: Pointer): Integer;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
procedure Delete(Index: Integer);
|
procedure Delete(Index: Integer);
|
||||||
@ -114,6 +118,8 @@ type
|
|||||||
property Current: T read GetCurrent;
|
property Current: T read GetCurrent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFPGList }
|
||||||
|
|
||||||
generic TFPGList<T> = class(TFPSList)
|
generic TFPGList<T> = class(TFPSList)
|
||||||
private
|
private
|
||||||
type
|
type
|
||||||
@ -133,6 +139,8 @@ type
|
|||||||
procedure SetLast(const Value: T); {$ifdef FGLINLINE} inline; {$endif}
|
procedure SetLast(const Value: T); {$ifdef FGLINLINE} inline; {$endif}
|
||||||
function GetFirst: T; {$ifdef FGLINLINE} inline; {$endif}
|
function GetFirst: T; {$ifdef FGLINLINE} inline; {$endif}
|
||||||
procedure SetFirst(const Value: T); {$ifdef FGLINLINE} inline; {$endif}
|
procedure SetFirst(const Value: T); {$ifdef FGLINLINE} inline; {$endif}
|
||||||
|
Protected
|
||||||
|
class Function ItemIsManaged : Boolean; override;
|
||||||
public
|
public
|
||||||
Type
|
Type
|
||||||
TFPGListEnumeratorSpec = specialize TFPGListEnumerator<T>;
|
TFPGListEnumeratorSpec = specialize TFPGListEnumerator<T>;
|
||||||
@ -460,6 +468,11 @@ begin
|
|||||||
System.Move(Src^, Dest^, FItemSize);
|
System.Move(Src^, Dest^, FItemSize);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFPSList.CopyItems(Src, Dest: Pointer; aCount: Integer);
|
||||||
|
begin
|
||||||
|
System.Move(Src^, Dest^, FItemSize*aCount);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TFPSList.RaiseIndexError(Index : Integer);
|
procedure TFPSList.RaiseIndexError(Index : Integer);
|
||||||
begin
|
begin
|
||||||
Error(SListIndexError, Index);
|
Error(SListIndexError, Index);
|
||||||
@ -552,6 +565,11 @@ begin
|
|||||||
Error(SListIndexError, AIndex);
|
Error(SListIndexError, AIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TFPSList.ItemIsManaged: Boolean;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TFPSList.Clear;
|
procedure TFPSList.Clear;
|
||||||
begin
|
begin
|
||||||
@ -838,8 +856,21 @@ var
|
|||||||
begin
|
begin
|
||||||
if Obj.ItemSize <> FItemSize then
|
if Obj.ItemSize <> FItemSize then
|
||||||
Error(SListItemSizeError, 0);
|
Error(SListItemSizeError, 0);
|
||||||
for I := 0 to Obj.Count - 1 do
|
// Do this now.
|
||||||
Add(Obj[i]);
|
Capacity:=Capacity+Obj.Count;
|
||||||
|
if ItemIsManaged then
|
||||||
|
begin
|
||||||
|
// nothing for it, need to do it manually to give deref a chance.
|
||||||
|
For I:=0 to Obj.Count-1 do
|
||||||
|
Add(Obj[i])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if Obj.Count=0 then
|
||||||
|
exit;
|
||||||
|
CopyItems(Obj.InternalItems[0],InternalItems[FCount],Obj.Count);
|
||||||
|
FCount:=FCount+Obj.Count;
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TFPSList.Assign(Obj: TFPSList);
|
procedure TFPSList.Assign(Obj: TFPSList);
|
||||||
@ -890,7 +921,7 @@ end;
|
|||||||
|
|
||||||
procedure TFPGList.Deref(Item: Pointer);
|
procedure TFPGList.Deref(Item: Pointer);
|
||||||
begin
|
begin
|
||||||
Finalize(T(Item^));
|
Finalize(T(Item^));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFPGList.Get(Index: Integer): T;
|
function TFPGList.Get(Index: Integer): T;
|
||||||
@ -936,6 +967,11 @@ begin
|
|||||||
inherited SetFirst(@Value);
|
inherited SetFirst(@Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TFPGList.ItemIsManaged: Boolean;
|
||||||
|
begin
|
||||||
|
Result:=IsManagedType(T);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFPGList.GetEnumerator: TFPGListEnumeratorSpec;
|
function TFPGList.GetEnumerator: TFPGListEnumeratorSpec;
|
||||||
begin
|
begin
|
||||||
Result := TFPGListEnumeratorSpec.Create(Self);
|
Result := TFPGListEnumeratorSpec.Create(Self);
|
||||||
@ -976,14 +1012,25 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
for I := 0 to Source.Count - 1 do
|
if IsManagedType(T) then
|
||||||
Add(Source[i]);
|
begin
|
||||||
|
Capacity:=Capacity+Source.Count;
|
||||||
|
for I := 0 to Source.Count - 1 do
|
||||||
|
Add(Source[i]);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Inherited AddList(TFPSList(source))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TFPGList.Assign(Source: TFPGList);
|
procedure TFPGList.Assign(Source: TFPGList);
|
||||||
begin
|
begin
|
||||||
Clear;
|
if IsManagedType(T) then
|
||||||
AddList(Source);
|
begin
|
||||||
|
Clear;
|
||||||
|
AddList(Source);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Inherited Assign(TFPSList(source))
|
||||||
end;
|
end;
|
||||||
{$endif VER2_4}
|
{$endif VER2_4}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user