Skip to content

Commit 3f5b10b

Browse files
committed
optimized sorting
1 parent dd0d0fb commit 3f5b10b

File tree

4 files changed

+1604
-223
lines changed

4 files changed

+1604
-223
lines changed

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

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ implementation
413413
Spring.Events.Base,
414414
Spring.ResourceStrings;
415415

416+
type
417+
TArray = class(Spring.TArray);
418+
416419

417420
{$REGION 'TAbstractArrayList<T>'}
418421

@@ -1100,23 +1103,103 @@ procedure TAbstractArrayList<T>.Sort(const comparer: TComparison<T>; index, coun
11001103
end;
11011104

11021105
procedure TAbstractArrayList<T>.Sort(const comparer: IComparer<T>; index, count: Integer);
1106+
var
1107+
listCount: Integer;
1108+
compare: TMethod;
11031109
begin
1104-
CheckRange(index, count, Self.Count);
1110+
listCount := Self.Count;
1111+
if Cardinal(index) <= Cardinal(listCount) then
1112+
{$Q-}
1113+
if (count >= 0) and (index <= listCount - count) then
1114+
{$IFDEF OVERFLOWCHECKS_ON}{$Q+}{$ENDIF}
1115+
begin
1116+
if count < 2 then
1117+
Exit;
11051118

1106-
if count < 2 then
1107-
Exit;
1119+
{$Q-}
1120+
Inc(fVersion);
1121+
{$IFDEF OVERFLOWCHECKS_ON}{$Q+}{$ENDIF}
1122+
{$IFDEF DELPHIXE7_UP}
1123+
if GetTypeKind(T) = tkClass then
1124+
TTimSort.Sort(fItems, IComparer<Pointer>(comparer), index, count)
1125+
else
1126+
{$ENDIF}
1127+
begin
1128+
compare.Data := Pointer(comparer);
1129+
compare.Code := PPVTable(comparer)^[3];
1130+
{$R-}
1131+
{$IFDEF DELPHIXE7_UP}
1132+
case GetTypeKind(T) of
1133+
tkInteger, tkChar, tkEnumeration, tkClass, tkWChar, tkLString, tkWString,
1134+
tkInterface, tkInt64, tkDynArray, tkUString, tkClassRef, tkPointer, tkProcedure:
1135+
case SizeOf(T) of
1136+
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1137+
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1138+
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1139+
8: TArray.IntroSort_Int64(@fItems[index], index + count - 1, @compare);
1140+
end;
1141+
tkFloat:
1142+
case SizeOf(T) of
1143+
4: TArray.IntroSort_Single(@fItems[index], index + count - 1, @compare);
1144+
10,16: TArray.IntroSort_Extended(@fItems[index], index + count - 1, @compare);
1145+
else
1146+
if GetTypeData(TypeInfo(T)).FloatType = ftDouble then
1147+
TArray.IntroSort_Double(@fItems[index], index + count - 1, @compare)
1148+
else
1149+
TArray.IntroSort_Int64(@fItems[index], index + count - 1, @compare);
1150+
end;
1151+
tkString:
1152+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T));
1153+
tkSet:
1154+
case SizeOf(T) of
1155+
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1156+
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1157+
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1158+
else
1159+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T));
1160+
end;
1161+
tkMethod:
1162+
TArray.IntroSort_Method(@fItems[index], index + count - 1, @compare);
1163+
tkVariant,
1164+
{$IF Declared(tkMRecord)}
1165+
tkMRecord,
1166+
{$IFEND}
1167+
tkRecord:
1168+
if not System.HasWeakRef(T) then
1169+
case SizeOf(T) of
1170+
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1171+
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1172+
3: TArray.IntroSort_Int24(@fItems[index], index + count - 1, @compare);
1173+
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1174+
else
1175+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T))
1176+
end
1177+
else
1178+
TArray.IntroSort<T>(Slice(TSlice<T>((@fItems[index])^), count), TCompareMethod<T>(compare));
1179+
tkArray:
1180+
case SizeOf(T) of
1181+
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1182+
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1183+
3: TArray.IntroSort_Int24(@fItems[index], index + count - 1, @compare);
1184+
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1185+
else
1186+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T));
1187+
end;
1188+
else
1189+
{$ELSE}
1190+
begin
1191+
{$ENDIF}
1192+
TArray.IntroSort<T>(Slice(TSlice<T>((@fItems[index])^), count), TCompareMethod<T>(compare));
1193+
end;
1194+
{$IFDEF RANGECHECKS_ON}{$R+}{$ENDIF}
1195+
end;
11081196

1109-
{$Q-}
1110-
Inc(fVersion);
1111-
{$IFDEF OVERFLOWCHECKS_ON}{$Q+}{$ENDIF}
1112-
{$IFDEF DELPHIXE7_UP}
1113-
if GetTypeKind(T) = tkClass then
1114-
TTimSort.Sort(fItems, IComparer<Pointer>(comparer), index, count)
1197+
Reset;
1198+
end
1199+
else
1200+
RaiseHelper.ArgumentOutOfRange_Count
11151201
else
1116-
{$ENDIF}
1117-
TArray.Sort<T>(fItems, comparer, index, count);
1118-
1119-
Reset;
1202+
RaiseHelper.ArgumentOutOfRange_Index;
11201203
end;
11211204

11221205
procedure TAbstractArrayList<T>.Move(currentIndex, newIndex: Integer);

0 commit comments

Comments
 (0)