Skip to content

Commit e0090cb

Browse files
committed
optimized introsort
1 parent 183e254 commit e0090cb

File tree

2 files changed

+333
-365
lines changed

2 files changed

+333
-365
lines changed

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

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,6 @@ procedure TAbstractArrayList<T>.Sort(const comparer: TComparison<T>; index, coun
11181118
procedure TAbstractArrayList<T>.Sort(const comparer: IComparer<T>; index, count: Integer);
11191119
var
11201120
listCount: Integer;
1121-
compare: TMethod;
11221121
begin
11231122
listCount := Self.Count;
11241123
if Cardinal(index) <= Cardinal(listCount) then
@@ -1138,71 +1137,69 @@ procedure TAbstractArrayList<T>.Sort(const comparer: IComparer<T>; index, count:
11381137
else
11391138
{$ENDIF}
11401139
begin
1141-
compare.Data := Pointer(comparer);
1142-
compare.Code := PPVTable(comparer)^[3];
11431140
{$R-}
11441141
{$IFDEF DELPHIXE7_UP}
11451142
case GetTypeKind(T) of
11461143
tkInteger, tkChar, tkEnumeration, tkClass, tkWChar, tkLString, tkWString,
11471144
tkInterface, tkInt64, tkDynArray, tkUString, tkClassRef, tkPointer, tkProcedure:
11481145
case SizeOf(T) of
1149-
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1150-
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1151-
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1152-
8: TArray.IntroSort_Int64(@fItems[index], index + count - 1, @compare);
1146+
1: TArray.IntroSort_Int8(Slice(TSlice<Int8>((@fItems[index])^), count), IComparer<Int8>(comparer));
1147+
2: TArray.IntroSort_Int16(Slice(TSlice<Int16>((@fItems[index])^), count), IComparer<Int16>(comparer));
1148+
4: TArray.IntroSort_Int32(Slice(TSlice<Int32>((@fItems[index])^), count), IComparer<Int32>(comparer));
1149+
8: TArray.IntroSort_Int64(Slice(TSlice<Int64>((@fItems[index])^), count), IComparer<Int64>(comparer));
11531150
end;
11541151
tkFloat:
11551152
case SizeOf(T) of
1156-
4: TArray.IntroSort_Single(@fItems[index], index + count - 1, @compare);
1157-
10,16: TArray.IntroSort_Extended(@fItems[index], index + count - 1, @compare);
1153+
4: TArray.IntroSort_Single(Slice(TSlice<System.Single>((@fItems[index])^), count), IComparer<System.Single>(comparer));
1154+
10,16: TArray.IntroSort_Extended(Slice(TSlice<Extended>((@fItems[index])^), count), IComparer<Extended>(comparer));
11581155
else
11591156
if GetTypeData(TypeInfo(T)).FloatType = ftDouble then
1160-
TArray.IntroSort_Double(@fItems[index], index + count - 1, @compare)
1157+
TArray.IntroSort_Double(Slice(TSlice<Double>((@fItems[index])^), count), IComparer<Double>(comparer))
11611158
else
1162-
TArray.IntroSort_Int64(@fItems[index], index + count - 1, @compare);
1159+
TArray.IntroSort_Int64(Slice(TSlice<Int64>((@fItems[index])^), count), IComparer<Int64>(comparer));
11631160
end;
11641161
tkString:
1165-
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T));
1162+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, IComparerRef(comparer), SizeOf(T));
11661163
tkSet:
11671164
case SizeOf(T) of
1168-
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1169-
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1170-
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1165+
1: TArray.IntroSort_Int8(Slice(TSlice<Int8>((@fItems[index])^), count), IComparer<Int8>(comparer));
1166+
2: TArray.IntroSort_Int16(Slice(TSlice<Int16>((@fItems[index])^), count), IComparer<Int16>(comparer));
1167+
4: TArray.IntroSort_Int32(Slice(TSlice<Int32>((@fItems[index])^), count), IComparer<Int32>(comparer));
11711168
else
1172-
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T));
1169+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, IComparerRef(comparer), SizeOf(T));
11731170
end;
11741171
tkMethod:
1175-
TArray.IntroSort_Method(@fItems[index], index + count - 1, @compare);
1172+
TArray.IntroSort_Method(Slice(TSlice<TMethodPointer>((@fItems[index])^), count), IComparer<TMethodPointer>(comparer));
11761173
tkVariant,
11771174
{$IF Declared(tkMRecord)}
11781175
tkMRecord,
11791176
{$IFEND}
11801177
tkRecord:
11811178
if not System.HasWeakRef(T) then
11821179
case SizeOf(T) of
1183-
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1184-
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1185-
3: TArray.IntroSort_Int24(@fItems[index], index + count - 1, @compare);
1186-
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1180+
1: TArray.IntroSort_Int8(Slice(TSlice<Int8>((@fItems[index])^), count), IComparer<Int8>(comparer));
1181+
2: TArray.IntroSort_Int16(Slice(TSlice<Int16>((@fItems[index])^), count), IComparer<Int16>(comparer));
1182+
3: TArray.IntroSort_Int24(Slice(TSlice<Int24>((@fItems[index])^), count), IComparer<Int24>(comparer));
1183+
4: TArray.IntroSort_Int32(Slice(TSlice<Int32>((@fItems[index])^), count), IComparer<Int32>(comparer));
11871184
else
1188-
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T))
1185+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, IComparerRef(comparer), SizeOf(T))
11891186
end
11901187
else
1191-
TArray.IntroSort<T>(Slice(TSlice<T>((@fItems[index])^), count), TCompareMethod<T>(compare));
1188+
TArray.IntroSort<T>(Slice(TSlice<T>((@fItems[index])^), count), comparer);
11921189
tkArray:
11931190
case SizeOf(T) of
1194-
1: TArray.IntroSort_Int8(@fItems[index], index + count - 1, @compare);
1195-
2: TArray.IntroSort_Int16(@fItems[index], index + count - 1, @compare);
1196-
3: TArray.IntroSort_Int24(@fItems[index], index + count - 1, @compare);
1197-
4: TArray.IntroSort_Int32(@fItems[index], index + count - 1, @compare);
1191+
1: TArray.IntroSort_Int8(Slice(TSlice<Int8>((@fItems[index])^), count), IComparer<Int8>(comparer));
1192+
2: TArray.IntroSort_Int16(Slice(TSlice<Int16>((@fItems[index])^), count), IComparer<Int16>(comparer));
1193+
3: TArray.IntroSort_Int24(Slice(TSlice<Int24>((@fItems[index])^), count), IComparer<Int24>(comparer));
1194+
4: TArray.IntroSort_Int32(Slice(TSlice<Int32>((@fItems[index])^), count), IComparer<Int32>(comparer));
11981195
else
1199-
TArray.IntroSort_Ref(@fItems[index], index + count - 1, TCompareMethod(compare), SizeOf(T));
1196+
TArray.IntroSort_Ref(@fItems[index], index + count - 1, IComparerRef(comparer), SizeOf(T));
12001197
end;
12011198
else
12021199
{$ELSE}
12031200
begin
12041201
{$ENDIF}
1205-
TArray.IntroSort<T>(Slice(TSlice<T>((@fItems[index])^), count), TCompareMethod<T>(compare));
1202+
TArray.IntroSort<T>(Slice(TSlice<T>((@fItems[index])^), count), comparer);
12061203
end;
12071204
{$IFDEF RANGECHECKS_ON}{$R+}{$ENDIF}
12081205
end;

0 commit comments

Comments
 (0)