Skip to content

Commit a17ae80

Browse files
committed
removed equals inlining from TEnumerableBase
1 parent 9c0c934 commit a17ae80

File tree

3 files changed

+47
-58
lines changed

3 files changed

+47
-58
lines changed

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

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ TEnumerableBase<T> = class abstract(TEnumerableBase)
5959
function GetComparer: IComparer<T>;
6060
function GetElementType: PTypeInfo; virtual;
6161
{$ENDREGION}
62-
function Equals(const left, right: T): Boolean; reintroduce; inline;
6362
function QueryInterface(const IID: TGUID; out obj): HResult; stdcall;
6463
procedure CopyTo(var values: TArray<T>; index: Integer);
6564
function TryGetElementAt(var value: T; index: Integer): Boolean;
@@ -69,7 +68,6 @@ TEnumerableBase<T> = class abstract(TEnumerableBase)
6968
function TryGetLast(var value: T; const predicate: Predicate<T>): Boolean; overload;
7069
function TryGetSingle(var value: T): Boolean; overload;
7170
function TryGetSingle(var value: T; const predicate: Predicate<T>): Boolean; overload;
72-
function UseComparer(typeKind: TTypeKind): Boolean; inline;
7371
property Comparer: IComparer<T> read fComparer;
7472
public
7573
constructor Create;
@@ -835,16 +833,6 @@ constructor TEnumerableBase<T>.Create;
835833
fComparer := IComparer<T>(_LookupVtableInfo(giComparer, GetElementType, SizeOf(T)));
836834
end;
837835

838-
function TEnumerableBase<T>.UseComparer(typeKind: TTypeKind): Boolean;
839-
const
840-
FastComparableTypes = [tkUnknown, tkInteger, tkChar, tkEnumeration, tkSet,
841-
tkClass, tkMethod, tkWChar, tkInterface, tkInt64,
842-
tkUString, tkClassRef, tkPointer, tkProcedure];
843-
begin
844-
Result := not ((typeKind in FastComparableTypes) and (SizeOf(T) in [1, 2, 4, 8])
845-
and ((fComparer = nil) or (Pointer(fComparer) = _LookupVtableInfo(giComparer, TypeInfo(T), SizeOf(T)))));
846-
end;
847-
848836
function TEnumerableBase<T>.Aggregate(const func: Func<T, T, T>): T;
849837
var
850838
enumerator: IEnumerator<T>;
@@ -975,40 +963,19 @@ function TEnumerableBase<T>.ElementAtOrDefault(index: Integer;
975963
Result := defaultValue;
976964
end;
977965

978-
function TEnumerableBase<T>.Equals(const left, right: T): Boolean;
979-
begin
980-
if TType.Kind<T> = tkClass then
981-
if PObject(@left)^ = nil then
982-
Result := PObject(@right)^ = nil
983-
else
984-
Result := PObject(@left).Equals(PObject(@right)^)
985-
else
986-
if UseComparer(TType.Kind<T>) then
987-
Result := fComparer.Compare(left, right) = 0
988-
else
989-
if TType.Kind<T> = tkUString then
990-
Result := PString(@left)^ = PString(@right)^
991-
else
992-
case SizeOf(T) of
993-
1: Result := PByte(@left)^ = PByte(@right)^;
994-
2: Result := PWord(@left)^ = PWord(@right)^;
995-
4: Result := PCardinal(@left)^ = PCardinal(@right)^;
996-
8: Result := PUInt64(@left)^ = PUInt64(@right)^;
997-
end;
998-
end;
999-
1000966
function TEnumerableBase<T>.EqualsTo(const values: array of T): Boolean;
1001967
var
1002-
e: IEnumerator<T>;
968+
enumerator: IEnumerator<T>;
969+
comparer: IEqualityComparer<T>;
1003970
i: Integer;
1004971
begin
1005-
e := IEnumerable<T>(this).GetEnumerator;
1006972
i := 0;
1007-
1008-
while e.MoveNext do
973+
enumerator := IEnumerable<T>(this).GetEnumerator;
974+
comparer := IEqualityComparer<T>(_LookupVtableInfo(giEqualityComparer, GetElementType, SizeOf(T)));
975+
while enumerator.MoveNext and (i < Length(values)) do
1009976
begin
1010-
if not ((i < Length(values)) and Equals(e.Current, values[i])) then
1011-
Exit(False);
977+
if not comparer.Equals(enumerator.Current, values[i]) then
978+
Break;
1012979
Inc(i);
1013980
end;
1014981
Result := i = Length(values);

Source/Base/Collections/Spring.Collections.LinkedLists.pas

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,14 @@ function TLinkedList<T>.Extract(const item: T): T;
295295
function TLinkedList<T>.Find(const value: T): TLinkedListNode<T>;
296296
var
297297
node: TLinkedListNode<T>;
298+
comparer: IEqualityComparer<T>;
298299
begin
299300
Result := nil;
300301
node := fHead;
301302
if Assigned(node) then
302303
begin
303-
while not Equals(node.fItem, value) do
304+
comparer := IEqualityComparer<T>(_LookupVtableInfo(giEqualityComparer, TypeInfo(T), SizeOf(T)));
305+
while not comparer.Equals(node.fItem, value) do
304306
begin
305307
node := node.fNext;
306308
if node = fHead then
@@ -313,14 +315,16 @@ function TLinkedList<T>.Find(const value: T): TLinkedListNode<T>;
313315
function TLinkedList<T>.FindLast(const value: T): TLinkedListNode<T>;
314316
var
315317
node1, node2: TLinkedListNode<T>;
318+
comparer: IEqualityComparer<T>;
316319
begin
317320
if not Assigned(fHead) then
318321
Exit(nil);
319322
node1 := fHead.fPrev;
320323
node2 := node1;
321324
if Assigned(node2) then
322325
begin
323-
while not Equals(node2.fItem, value) do
326+
comparer := IEqualityComparer<T>(_LookupVtableInfo(giEqualityComparer, TypeInfo(T), SizeOf(T)));
327+
while not comparer.Equals(node2.fItem, value) do
324328
begin
325329
node2 := node2.fPrev;
326330
if node2 = node1 then

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

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ interface
3232
Classes,
3333
Generics.Defaults,
3434
SysUtils,
35+
TypInfo,
3536
Spring,
3637
Spring.Collections,
3738
Spring.Collections.Base;
@@ -73,6 +74,7 @@ TEnumerator = class(TRefCountedObject, IEnumerator<T>)
7374
fCapacity: Integer;
7475
fCount: Integer;
7576
fVersion: Integer;
77+
function CanFastCompare: Boolean; inline;
7678
procedure Grow; overload;
7779
{$IFNDEF DELPHIXE8_UP}{$HINTS OFF}{$ENDIF}
7880
procedure Grow(capacity: Integer); overload;
@@ -365,13 +367,17 @@ TObservableInterfaceList = class(TFoldedList<IInterface>, INotifyPropertyChang
365367
property OnPropertyChanged: IEvent<TPropertyChangedEvent> read GetOnPropertyChanged;
366368
end;
367369

370+
const
371+
FastComparableTypes = [tkUnknown, tkInteger, tkChar, tkEnumeration, tkSet,
372+
tkClass, tkMethod, tkWChar, tkInterface, tkInt64,
373+
tkUString, tkClassRef, tkPointer, tkProcedure];
374+
368375
implementation
369376

370377
uses
371378
{$IFDEF DELPHIXE4}
372379
Rtti, // suppress hint about inlining
373380
{$ENDIF}
374-
TypInfo,
375381
Spring.Collections.Extensions,
376382
Spring.Events,
377383
Spring.Events.Base,
@@ -392,6 +398,12 @@ destructor TAbstractArrayList<T>.Destroy;
392398
inherited Destroy;
393399
end;
394400

401+
function TAbstractArrayList<T>.CanFastCompare: Boolean;
402+
begin
403+
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))));
405+
end;
406+
395407
function TAbstractArrayList<T>.GetCapacity: Integer;
396408
begin
397409
Result := fCapacity;
@@ -502,14 +514,8 @@ function TAbstractArrayList<T>.IndexOf(const item: T; index, count: Integer): In
502514

503515
if TType.Kind<T> = tkClass then
504516
Result := TArrayHelper.IndexOfObj(fItems, item, index, count)
505-
else if UseComparer(TType.Kind<T>) then
517+
else if CanFastCompare then
506518
begin
507-
for Result := index to index + count - 1 do
508-
if Comparer.Compare(fItems[Result], item) = 0 then
509-
Exit;
510-
Result := -1;
511-
end
512-
else
513519
if TType.Kind<T> = tkUString then
514520
Result := TArrayHelper.IndexOfStr(fItems, item, index, count)
515521
else
@@ -519,6 +525,14 @@ function TAbstractArrayList<T>.IndexOf(const item: T; index, count: Integer): In
519525
4: Result := TArrayHelper.IndexOf4(fItems, item, index, count);
520526
8: Result := TArrayHelper.IndexOf8(fItems, item, index, count);
521527
end;
528+
end
529+
else
530+
begin
531+
for Result := index to index + count - 1 do
532+
if Comparer.Compare(fItems[Result], item) = 0 then
533+
Exit;
534+
Result := -1;
535+
end;
522536
end;
523537

524538
procedure TAbstractArrayList<T>.SetItem(index: Integer; const value: T);
@@ -765,14 +779,8 @@ function TAbstractArrayList<T>.LastIndexOf(const item: T; index, count: Integer)
765779

766780
if TType.Kind<T> = tkClass then
767781
Result := TArrayHelper.LastIndexOfStr(fItems, item, index, count)
768-
else if UseComparer(TType.Kind<T>) then
782+
else if CanFastCompare then
769783
begin
770-
for Result := index downto index - count do
771-
if Comparer.Compare(fItems[Result], item) = 0 then
772-
Exit;
773-
Result := -1;
774-
end
775-
else
776784
if TType.Kind<T> = tkUString then
777785
Result := TArrayHelper.LastIndexOfStr(fItems, item, index, count)
778786
else
@@ -782,6 +790,14 @@ function TAbstractArrayList<T>.LastIndexOf(const item: T; index, count: Integer)
782790
4: Result := TArrayHelper.LastIndexOf4(fItems, item, index, count);
783791
8: Result := TArrayHelper.LastIndexOf8(fItems, item, index, count);
784792
end;
793+
end
794+
else
795+
begin
796+
for Result := index downto index - count do
797+
if Comparer.Compare(fItems[Result], item) = 0 then
798+
Exit;
799+
Result := -1;
800+
end;
785801
end;
786802

787803
procedure TAbstractArrayList<T>.DeleteInternal(index: Integer;
@@ -1948,10 +1964,12 @@ function TAnonymousReadOnlyList<T>.IndexOf(const item: T;
19481964
function TAnonymousReadOnlyList<T>.IndexOf(const item: T; index,
19491965
count: Integer): Integer;
19501966
var
1967+
comparer: IEqualityComparer<T>;
19511968
i: Integer;
19521969
begin
1970+
comparer := IEqualityComparer<T>(_LookupVtableInfo(giEqualityComparer, TypeInfo(T), SizeOf(T)));
19531971
for i := index to index + count - 1 do
1954-
if Equals(fItems(i), item) then
1972+
if Comparer.Equals(fItems(i), item) then
19551973
Exit(i);
19561974
Result := -1;
19571975
end;

0 commit comments

Comments
 (0)