Skip to content

Commit 9a1fc4a

Browse files
committed
replaced for-in loop with explicit while loop to reduce generated code
1 parent 822d573 commit 9a1fc4a

File tree

6 files changed

+171
-47
lines changed

6 files changed

+171
-47
lines changed

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

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -880,29 +880,39 @@ function TEnumerableBase<T>.Aggregate(const func: Func<T, T, T>): T;
880880

881881
function TEnumerableBase<T>.All(const predicate: Predicate<T>): Boolean;
882882
var
883+
enumerator: IEnumerator<T>;
883884
item: T;
884885
begin
885886
{$IFDEF SPRING_ENABLE_GUARD}
886887
Guard.CheckNotNull(Assigned(predicate), 'predicate');
887888
{$ENDIF}
888889

889-
for item in IEnumerable<T>(this) do
890+
enumerator := IEnumerable<T>(this).GetEnumerator;
891+
while enumerator.MoveNext do
892+
begin
893+
item := enumerator.Current;
890894
if not predicate(item) then
891895
Exit(False);
896+
end;
892897
Result := True;
893898
end;
894899

895900
function TEnumerableBase<T>.Any(const predicate: Predicate<T>): Boolean;
896901
var
902+
enumerator: IEnumerator<T>;
897903
item: T;
898904
begin
899905
{$IFDEF SPRING_ENABLE_GUARD}
900906
Guard.CheckNotNull(Assigned(predicate), 'predicate');
901907
{$ENDIF}
902908

903-
for item in IEnumerable<T>(this) do
909+
enumerator := IEnumerable<T>(this).GetEnumerator;
910+
while enumerator.MoveNext do
911+
begin
912+
item := enumerator.Current;
904913
if predicate(item) then
905914
Exit(True);
915+
end;
906916
Result := False;
907917
end;
908918

@@ -928,15 +938,20 @@ function TEnumerableBase<T>.Contains(const value: T): Boolean;
928938
function TEnumerableBase<T>.Contains(const value: T;
929939
const comparer: IEqualityComparer<T>): Boolean;
930940
var
941+
enumerator: IEnumerator<T>;
931942
item: T;
932943
begin
933944
{$IFDEF SPRING_ENABLE_GUARD}
934945
Guard.CheckNotNull(Assigned(comparer), 'comparer');
935946
{$ENDIF}
936947

937-
for item in IEnumerable<T>(this) do
948+
enumerator := IEnumerable<T>(this).GetEnumerator;
949+
while enumerator.MoveNext do
950+
begin
951+
item := enumerator.Current;
938952
if comparer.Equals(value, item) then
939953
Exit(True);
954+
end;
940955
Result := False;
941956
end;
942957

@@ -1084,14 +1099,19 @@ function TEnumerableBase<T>.FirstOrDefault(const predicate: Predicate<T>;
10841099

10851100
procedure TEnumerableBase<T>.ForEach(const action: Action<T>);
10861101
var
1102+
enumerator: IEnumerator<T>;
10871103
item: T;
10881104
begin
10891105
{$IFDEF SPRING_ENABLE_GUARD}
10901106
Guard.CheckNotNull(Assigned(action), 'action');
10911107
{$ENDIF}
10921108

1093-
for item in IEnumerable<T>(this) do
1109+
enumerator := IEnumerable<T>(this).GetEnumerator;
1110+
while enumerator.MoveNext do
1111+
begin
1112+
item := enumerator.Current;
10941113
action(item);
1114+
end;
10951115
end;
10961116

10971117
function TEnumerableBase<T>.GetComparer: IComparer<T>;
@@ -1401,10 +1421,14 @@ function TEnumerableBase<T>.SkipWhile(
14011421

14021422
function TEnumerableBase<T>.Sum: T;
14031423
var
1424+
enumerator: IEnumerator<T>;
14041425
item: T;
14051426
begin
14061427
Result := Default(T);
1407-
for item in IEnumerable<T>(this) do
1428+
enumerator := IEnumerable<T>(this).GetEnumerator;
1429+
while enumerator.MoveNext do
1430+
begin
1431+
item := enumerator.Current;
14081432
case TType.Kind<T> of
14091433
tkInteger: PInteger(@Result)^ := PInteger(@Result)^ + PInteger(@item)^;
14101434
tkInt64: PInt64(@Result)^ := PInt64(@Result)^ + PInt64(@item)^;
@@ -1414,6 +1438,7 @@ function TEnumerableBase<T>.Sum: T;
14141438
ftDouble: PDouble(@Result)^ := PDouble(@Result)^ + PDouble(@item)^;
14151439
end;
14161440
end;
1441+
end;
14171442
end;
14181443

14191444
function TEnumerableBase<T>.Take(count: Integer): IEnumerable<T>;
@@ -1446,30 +1471,30 @@ function TEnumerableBase<T>.TakeWhile(
14461471

14471472
function TEnumerableBase<T>.ToArray: TArray<T>;
14481473
var
1449-
collection: ICollection<T>;
1474+
intf: IInterface;
14501475
count: Integer;
1451-
item: T;
14521476
begin
14531477
Result := nil;
1454-
if Supports(Self, ICollection<T>, collection) then
1478+
if Supports(Self, ICollection<T>, intf) then
14551479
begin
1456-
count := collection.Count;
1480+
count := ICollection<T>(intf).Count;
14571481
if count > 0 then
14581482
begin
14591483
SetLength(Result, count);
1460-
collection.CopyTo(Result, 0);
1484+
ICollection<T>(intf).CopyTo(Result, 0);
14611485
end;
14621486
end
14631487
else
14641488
begin
14651489
count := 0;
1466-
for item in IEnumerable<T>(this) do
1490+
intf := IEnumerable<T>(this).GetEnumerator;
1491+
while IEnumerator<T>(intf).MoveNext do
14671492
begin
14681493
if Result = nil then
14691494
SetLength(Result, 4)
14701495
else if Length(Result) = count then
14711496
SetLength(Result, count * 2);
1472-
Result[count] := item;
1497+
Result[count] := IEnumerator<T>(intf).Current;
14731498
Inc(count);
14741499
end;
14751500
SetLength(Result, count);
@@ -1511,18 +1536,23 @@ function TEnumerableBase<T>.TryGetFirst(var value: T): Boolean;
15111536

15121537
function TEnumerableBase<T>.TryGetFirst(var value: T; const predicate: Predicate<T>): Boolean;
15131538
var
1539+
enumerator: IEnumerator<T>;
15141540
item: T;
15151541
begin
15161542
{$IFDEF SPRING_ENABLE_GUARD}
15171543
Guard.CheckNotNull(Assigned(predicate), 'predicate');
15181544
{$ENDIF}
15191545

1520-
for item in IEnumerable<T>(this) do
1546+
enumerator := IEnumerable<T>(this).GetEnumerator;
1547+
while enumerator.MoveNext do
1548+
begin
1549+
item := enumerator.Current;
15211550
if predicate(item) then
15221551
begin
15231552
value := item;
15241553
Exit(True);
15251554
end;
1555+
end;
15261556
value := Default(T);
15271557
Result := False;
15281558
end;
@@ -1545,15 +1575,18 @@ function TEnumerableBase<T>.TryGetLast(var value: T): Boolean;
15451575

15461576
function TEnumerableBase<T>.TryGetLast(var value: T; const predicate: Predicate<T>): Boolean;
15471577
var
1578+
enumerator: IEnumerator<T>;
15481579
item: T;
15491580
begin
15501581
{$IFDEF SPRING_ENABLE_GUARD}
15511582
Guard.CheckNotNull(Assigned(predicate), 'predicate');
15521583
{$ENDIF}
15531584

15541585
Result := False;
1555-
for item in IEnumerable<T>(this) do
1586+
enumerator := IEnumerable<T>(this).GetEnumerator;
1587+
while enumerator.MoveNext do
15561588
begin
1589+
item := enumerator.Current;
15571590
if predicate(item) then
15581591
begin
15591592
value := item;
@@ -1586,14 +1619,19 @@ function TEnumerableBase<T>.TryGetSingle(var value: T): Boolean;
15861619
function TEnumerableBase<T>.TryGetSingle(var value: T;
15871620
const predicate: Predicate<T>): Boolean;
15881621
var
1622+
enumerator: IEnumerator<T>;
15891623
item: T;
15901624
begin
15911625
{$IFDEF SPRING_ENABLE_GUARD}
15921626
Guard.CheckNotNull(Assigned(predicate), 'predicate');
15931627
{$ENDIF}
15941628

15951629
Result := False;
1596-
for item in IEnumerable<T>(this) do
1630+
enumerator := IEnumerable<T>(this).GetEnumerator;
1631+
while enumerator.MoveNext do
1632+
begin
1633+
item := enumerator.Current;
1634+
15971635
if predicate(item) then
15981636
begin
15991637
if Result then
@@ -1604,6 +1642,7 @@ function TEnumerableBase<T>.TryGetSingle(var value: T;
16041642
value := item;
16051643
Result := True;
16061644
end;
1645+
end;
16071646
end;
16081647

16091648
function TEnumerableBase<T>.Where(const predicate: Predicate<T>): IEnumerable<T>;
@@ -1837,14 +1876,19 @@ procedure TCollectionBase<T>.AddRange(const values: array of T);
18371876

18381877
procedure TCollectionBase<T>.AddRange(const values: IEnumerable<T>);
18391878
var
1879+
enumerator: IEnumerator<T>;
18401880
item: T;
18411881
begin
18421882
{$IFDEF SPRING_ENABLE_GUARD}
18431883
Guard.CheckNotNull(Assigned(values), 'values');
18441884
{$ENDIF}
18451885

1846-
for item in values do
1886+
enumerator := values.GetEnumerator;
1887+
while enumerator.MoveNext do
1888+
begin
1889+
item := enumerator.Current;
18471890
ICollection<T>(this).Add(item);
1891+
end;
18481892
end;
18491893

18501894
procedure TCollectionBase<T>.Changed(const item: T; action: TCollectionChangedAction);
@@ -1855,15 +1899,16 @@ procedure TCollectionBase<T>.Changed(const item: T; action: TCollectionChangedAc
18551899

18561900
procedure TCollectionBase<T>.CopyTo(var values: TArray<T>; index: Integer);
18571901
var
1858-
item: T;
1902+
enumerator: IEnumerator<T>;
18591903
begin
18601904
{$IFDEF SPRING_ENABLE_GUARD}
18611905
Guard.CheckRange(Length(values), index, IEnumerable<T>(this).Count);
18621906
{$ENDIF}
18631907

1864-
for item in IEnumerable<T>(this) do
1908+
enumerator := IEnumerable<T>(this).GetEnumerator;
1909+
while enumerator.MoveNext do
18651910
begin
1866-
values[index] := item;
1911+
values[index] := enumerator.Current;
18671912
Inc(index);
18681913
end;
18691914
end;
@@ -1884,14 +1929,19 @@ procedure TCollectionBase<T>.ExtractRange(const values: array of T);
18841929

18851930
procedure TCollectionBase<T>.ExtractRange(const values: IEnumerable<T>);
18861931
var
1932+
enumerator: IEnumerator<T>;
18871933
item: T;
18881934
begin
18891935
{$IFDEF SPRING_ENABLE_GUARD}
18901936
Guard.CheckNotNull(Assigned(values), 'values');
18911937
{$ENDIF}
18921938

1893-
for item in values do
1939+
enumerator := values.GetEnumerator;
1940+
while enumerator.MoveNext do
1941+
begin
1942+
item := enumerator.Current;
18941943
ICollection<T>(this).Extract(item);
1944+
end;
18951945
end;
18961946

18971947
function TCollectionBase<T>.GetIsReadOnly: Boolean;
@@ -1970,16 +2020,21 @@ function TCollectionBase<T>.RemoveRange(const values: array of T): Integer;
19702020

19712021
function TCollectionBase<T>.RemoveRange(const values: IEnumerable<T>): Integer;
19722022
var
2023+
enumerator: IEnumerator<T>;
19732024
item: T;
19742025
begin
19752026
{$IFDEF SPRING_ENABLE_GUARD}
19762027
Guard.CheckNotNull(Assigned(values), 'values');
19772028
{$ENDIF}
19782029

19792030
Result := 0;
1980-
for item in values do
2031+
enumerator := values.GetEnumerator;
2032+
while enumerator.MoveNext do
2033+
begin
2034+
item := enumerator.Current;
19812035
if ICollection<T>(this).Remove(item) then
19822036
Inc(Result);
2037+
end;
19832038
end;
19842039

19852040
procedure TCollectionBase<T>.Reset;
@@ -2979,7 +3034,7 @@ function TIterator.MoveNext: Boolean;
29793034
end;
29803035
until fState = Finished;
29813036

2982-
fIterator.Finalize;
3037+
fIterator.Finalize;
29833038
Result := False;
29843039
end;
29853040

0 commit comments

Comments
 (0)