@@ -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+
368375implementation
369376
370377uses
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;
393399end ;
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+
395407function TAbstractArrayList <T>.GetCapacity: Integer;
396408begin
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 ;
522536end ;
523537
524538procedure 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 ;
785801end ;
786802
787803procedure TAbstractArrayList <T>.DeleteInternal(index: Integer;
@@ -1948,10 +1964,12 @@ function TAnonymousReadOnlyList<T>.IndexOf(const item: T;
19481964function TAnonymousReadOnlyList <T>.IndexOf(const item: T; index,
19491965 count: Integer): Integer;
19501966var
1967+ comparer: IEqualityComparer<T>;
19511968 i: Integer;
19521969begin
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 ;
19571975end ;
0 commit comments