Skip to content

Commit b5c371c

Browse files
committed
optimized Range enumerator
1 parent 1c0abe2 commit b5c371c

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

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

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,24 @@ TDistinctByIterator<T,TKey> = class(TSourceIterator<T>)
228228
TRangeIterator = class(TEnumerableBase<Integer>,
229229
IEnumerable<Integer>, IReadOnlyCollection<Integer>, IReadOnlyList<Integer>)
230230
private type
231-
TEnumerator = class(TRefCountedObject, IEnumerator<Integer>)
232-
private
233-
fCurrent, fCount: Integer;
234-
fStarted: Boolean;
231+
PEnumerator = ^TEnumerator;
232+
TEnumerator = record
233+
Vtable: Pointer;
234+
RefCount: Integer;
235+
fCurrent, fMax: Integer;
235236
function GetCurrent: Integer;
236-
public
237-
constructor Create(start, count: Integer);
238237
function MoveNext: Boolean;
238+
function _Release: Integer; stdcall;
239+
class function Create(start, count: Integer): IEnumerator<Integer>; static;
239240
end;
241+
const
242+
Enumerator_Vtable: TEnumeratorVtable = (
243+
@NopQueryInterface,
244+
@RecAddRef,
245+
@TEnumerator._Release,
246+
@TEnumerator.GetCurrent,
247+
@TEnumerator.MoveNext
248+
);
240249
private
241250
fStart, fCount: Integer;
242251
{$REGION 'Property Accessors'}
@@ -1493,10 +1502,19 @@ function TRangeIterator.TryGetElementAt(var value: Integer; index: Integer): Boo
14931502

14941503
{$REGION 'TRangeIterator.TEnumerator'}
14951504

1496-
constructor TRangeIterator.TEnumerator.Create(start, count: Integer);
1505+
class function TRangeIterator.TEnumerator.Create(start, count: Integer): IEnumerator<Integer>;
14971506
begin
1498-
fCurrent := start;
1499-
fCount := count;
1507+
Result := nil;
1508+
GetMem(Pointer(Result), SizeOf(TEnumerator));
1509+
with PEnumerator(Result)^ do
1510+
begin
1511+
Vtable := @Enumerator_Vtable;
1512+
RefCount := 1;
1513+
{$Q-}
1514+
fCurrent := start - 1;
1515+
{$IFDEF OVERFLOWCHECKS_ON}{$Q+}{$ENDIF}
1516+
fMax := fCurrent + count;
1517+
end;
15001518
end;
15011519

15021520
function TRangeIterator.TEnumerator.GetCurrent: Integer;
@@ -1506,15 +1524,15 @@ function TRangeIterator.TEnumerator.GetCurrent: Integer;
15061524

15071525
function TRangeIterator.TEnumerator.MoveNext: Boolean;
15081526
begin
1509-
Result := fCount > 0;
1510-
if Result then
1511-
begin
1512-
Dec(fCount);
1513-
if fStarted then
1514-
Inc(fCurrent)
1515-
else
1516-
fStarted := True;
1517-
end;
1527+
Result := fCurrent < fMax;
1528+
Inc(fCurrent, Byte(Result));
1529+
end;
1530+
1531+
function TRangeIterator.TEnumerator._Release: Integer;
1532+
begin
1533+
Result := AtomicDecrement(RefCount);
1534+
if Result = 0 then
1535+
FreeMem(@Self);
15181536
end;
15191537

15201538
{$ENDREGION}

0 commit comments

Comments
 (0)