Skip to content

Commit 5ea0e6b

Browse files
committed
optimization for InsertRange
1 parent 534d63b commit 5ea0e6b

File tree

1 file changed

+48
-55
lines changed

1 file changed

+48
-55
lines changed

Source/Base/Collections/Spring.Collections.Lists.pas

Lines changed: 48 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,11 @@ TEnumerator = class(TRefCountedObject, IEnumerator<T>)
7979
{$IFNDEF DELPHIXE8_UP}{$HINTS OFF}{$ENDIF}
8080
procedure Grow(capacity: Integer); overload;
8181
{$IFNDEF DELPHIXE8_UP}{$HINTS ON}{$ENDIF}
82-
procedure DeleteInternal(index: Integer; action: TCollectionChangedAction); inline;
82+
procedure DeleteInternal(index: Integer; action: TCollectionChangedAction);
8383
function DeleteAllInternal(const match: Predicate<T>;
8484
action: TCollectionChangedAction; const items: TArray<T>): Integer;
8585
procedure DeleteRangeInternal(index, count: Integer; doClear: Boolean);
8686
function InsertInternal(index: Integer; const item: T): Integer;
87-
procedure InsertRangeInternal(index, count: Integer; const values: array of T);
8887
procedure SetItemInternal(index: Integer; const value: T);
8988
protected
9089
{$REGION 'Property Accessors'}
@@ -401,7 +400,7 @@ destructor TAbstractArrayList<T>.Destroy;
401400
function TAbstractArrayList<T>.CanFastCompare: Boolean;
402401
begin
403402
Result := (TType.Kind<T> in FastComparableTypes) and (SizeOf(T) in [1, 2, 4, 8])
404-
and ((fComparer = nil) or (Pointer(fComparer) = _LookupVtableInfo(giComparer, TypeInfo(T), SizeOf(T))));
403+
and (Pointer(fComparer) = _LookupVtableInfo(giComparer, TypeInfo(T), SizeOf(T)));
405404
end;
406405

407406
function TAbstractArrayList<T>.GetCapacity: Integer;
@@ -465,7 +464,7 @@ function TAbstractArrayList<T>.GetItem(index: Integer): T;
465464

466465
function TAbstractArrayList<T>.GetRange(index, count: Integer): IList<T>;
467466
var
468-
list: TList<T>;
467+
list: TAbstractArrayList<T>;
469468
{$IFNDEF DELPHIXE2_UP}
470469
i: Integer;
471470
{$ENDIF}
@@ -476,7 +475,7 @@ function TAbstractArrayList<T>.GetRange(index, count: Integer): IList<T>;
476475
{$ENDIF}
477476

478477
Result := CreateList;
479-
list := TList<T>(Result.AsObject);
478+
list := TAbstractArrayList<T>(Result.AsObject);
480479
list.fCount := (list.fCount and OwnsObjectsMask) or count;
481480
{$IFDEF DELPHIXE2_UP}
482481
list.fItems := Copy(fItems, index, count);
@@ -648,17 +647,46 @@ function TAbstractArrayList<T>.InsertInternal(index: Integer;
648647

649648
procedure TAbstractArrayList<T>.InsertRange(index: Integer; const values: array of T);
650649
var
651-
itemCount: Integer;
650+
listCount, count, i: Integer;
652651
begin
653652
{$IFDEF SPRING_ENABLE_GUARD}
654-
Guard.CheckRange((index >= 0) and (index <= Count), 'index');
653+
Guard.CheckRange((index >= 0) and (index <= Self.Count), 'index');
655654
{$ENDIF}
656655

657-
itemCount := Length(values);
658-
if itemCount = 0 then
656+
count := Length(values);
657+
if count = 0 then
659658
Exit;
660659

661-
InsertRangeInternal(index, itemCount, values);
660+
listCount := Self.Count;
661+
if listCount + count > fCapacity then
662+
Grow(listCount + count);
663+
664+
{$Q-}
665+
Inc(fVersion);
666+
{$IFDEF OVERFLOWCHECKS_ON}{$Q+}{$ENDIF}
667+
if index <> listCount then
668+
begin
669+
if ItemType.HasWeakRef then
670+
ItemType.MoveSlow(fItems, index, index + count, listCount - index)
671+
else
672+
begin
673+
System.Move(fItems[index], fItems[index + count], SizeOf(T) * (listCount - index));
674+
if ItemType.IsManaged then
675+
System.FillChar(fItems[index], SizeOf(T) * count, 0);
676+
end;
677+
end;
678+
679+
if ItemType.IsManaged then
680+
for i := Low(values) to count - 1 do
681+
fItems[index + i] := values[i]
682+
else
683+
System.Move(values[0], fItems[index], SizeOf(T) * count);
684+
685+
Inc(fCount, count);
686+
687+
if Assigned(Notify) then
688+
for i := Low(values) to count - 1 do
689+
Notify(Self, values[i], caAdded);
662690
end;
663691

664692
procedure TAbstractArrayList<T>.InsertRange(index: Integer;
@@ -733,43 +761,6 @@ procedure TAbstractArrayList<T>.InsertRange(index: Integer;
733761
end;
734762
end;
735763

736-
procedure TAbstractArrayList<T>.InsertRangeInternal(index, count: Integer;
737-
const values: array of T);
738-
var
739-
listCount, i: Integer;
740-
begin
741-
listCount := Self.Count;
742-
if listCount + count > fCapacity then
743-
Grow(listCount + count);
744-
745-
{$Q-}
746-
Inc(fVersion);
747-
{$IFDEF OVERFLOWCHECKS_ON}{$Q+}{$ENDIF}
748-
if index <> listCount then
749-
begin
750-
if ItemType.HasWeakRef then
751-
ItemType.MoveSlow(fItems, index, index + count, listCount - index)
752-
else
753-
begin
754-
System.Move(fItems[index], fItems[index + count], SizeOf(T) * (listCount - index));
755-
if ItemType.IsManaged then
756-
System.FillChar(fItems[index], SizeOf(T) * count, 0);
757-
end;
758-
end;
759-
760-
if ItemType.IsManaged then
761-
for i := Low(values) to count - 1 do
762-
fItems[index + i] := values[i]
763-
else
764-
System.Move(values[0], fItems[index], SizeOf(T) * count);
765-
766-
Inc(fCount, count);
767-
768-
if Assigned(Notify) then
769-
for i := Low(values) to count - 1 do
770-
Notify(Self, values[i], caAdded);
771-
end;
772-
773764
function TAbstractArrayList<T>.LastIndexOf(const item: T; index, count: Integer): Integer;
774765
begin
775766
{$IFDEF SPRING_ENABLE_GUARD}
@@ -802,6 +793,8 @@ function TAbstractArrayList<T>.LastIndexOf(const item: T; index, count: Integer)
802793

803794
procedure TAbstractArrayList<T>.DeleteInternal(index: Integer;
804795
action: TCollectionChangedAction);
796+
label
797+
SkipClear;
805798
var
806799
listCount: Integer;
807800
arrayItem: PT;
@@ -824,18 +817,18 @@ procedure TAbstractArrayList<T>.DeleteInternal(index: Integer;
824817
if ItemType.IsManaged then
825818
arrayItem^ := Default(T);
826819
System.Move((arrayItem + 1)^, arrayItem^, SizeOf(T) * (listCount - index));
827-
arrayItem := @fItems[listCount];
828820
if ItemType.IsManaged then
821+
begin
829822
if SizeOf(T) = SizeOf(Pointer) then
830-
PPointer(arrayItem)^ := nil
823+
PPointer(@fItems[listCount])^ := nil
831824
else
832-
System.FillChar(arrayItem^, SizeOf(T), 0)
833-
else
834-
arrayItem^ := Default(T);
825+
System.FillChar(fItems[listCount], SizeOf(T), 0);
826+
goto SkipClear;
827+
end;
835828
end;
836-
end
837-
else
838-
fItems[listCount] := Default(T);
829+
end;
830+
fItems[listCount] := Default(T);
831+
SkipClear:
839832

840833
if Assigned(Notify) then
841834
Notify(Self, oldItem, action);

0 commit comments

Comments
 (0)