Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program EnumeratorPerformance;
- {$APPTYPE CONSOLE}
- {$OPTIMIZATION ON}
- {$STACKFRAMES OFF}
- uses
- Diagnostics,
- SysUtils,
- EnumeratorTypes in 'EnumeratorTypes.pas';
- type
- TEnumeratorRecord = record
- fCount: Integer;
- fCurrent: Integer;
- function MoveNext: Boolean; inline; // no effect - compiler will not inline
- property Current: Integer read fCurrent;
- end;
- TEnumeratorObject = class
- private
- fCount: Integer;
- fCurrent: Integer;
- public
- constructor Create(count: Integer);
- function MoveNext: Boolean; inline;
- property Current: Integer read fCurrent;
- end;
- IEnumerator = interface
- function GetCurrent: Integer;
- function MoveNext: Boolean;
- property Current: Integer read GetCurrent;
- end;
- TEnumeratorInterfacedObject = class(TInterfacedObject, IEnumerator)
- private
- fCount: Integer;
- fCurrent: Integer;
- public
- constructor Create(count: Integer);
- function GetCurrent: Integer;
- function MoveNext: Boolean;
- property Current: Integer read GetCurrent;
- end;
- TEnumerableBase = class
- protected
- fCount: Integer;
- public
- constructor Create(count: Integer);
- end;
- TEnumerableWithRecordEnumerator = class(TEnumerableBase)
- function GetEnumerator: TEnumeratorRecord;
- end;
- TEnumerableWithObjectEnumerator = class(TEnumerableBase)
- function GetEnumerator: TEnumeratorObject;
- end;
- TEnumerableWithInterfaceEnumerator = class(TEnumerableBase)
- function GetEnumerator: IEnumerator;
- end;
- const
- RunCount = 10000;
- ItemCount = 10000;
- procedure TestEnumeratorRecord;
- var
- e: TEnumerableWithRecordEnumerator;
- n: Integer;
- procedure Enumerate;
- var
- i: Integer;
- begin
- for i in e do;
- end;
- begin
- e := TEnumerableWithRecordEnumerator.Create(ItemCount);
- try
- for n := 1 to RunCount do
- Enumerate;
- finally
- e.Free;
- end;
- end;
- procedure TestEnumeratorObject;
- var
- e: TEnumerableWithObjectEnumerator;
- n: Integer;
- procedure Enumerate;
- var
- i: Integer;
- begin
- for i in e do;
- end;
- begin
- e := TEnumerableWithObjectEnumerator.Create(ItemCount);
- try
- for n := 1 to RunCount do
- Enumerate;
- finally
- e.Free;
- end;
- end;
- procedure TestEnumeratorInterface;
- var
- e: TEnumerableWithInterfaceEnumerator;
- n: Integer;
- procedure Enumerate;
- var
- i: Integer;
- begin
- for i in e do;
- end;
- begin
- e := TEnumerableWithInterfaceEnumerator.Create(ItemCount);
- try
- for n := 1 to RunCount do
- Enumerate;
- finally
- e.Free;
- end;
- end;
- procedure Main;
- var
- sw: TStopwatch;
- begin
- sw := TStopwatch.StartNew;
- TestEnumeratorRecord;
- Writeln('record: ', sw.ElapsedMilliseconds);
- sw := TStopwatch.StartNew;
- TestEnumeratorObject;
- Writeln('object: ', sw.ElapsedMilliseconds);
- sw := TStopwatch.StartNew;
- TestEnumeratorInterface;
- Writeln('interface: ', sw.ElapsedMilliseconds);
- end;
- { TEnumerableBase }
- constructor TEnumerableBase.Create(count: Integer);
- begin
- inherited Create;
- fCount := count;
- end;
- { TEnumeratorRecord }
- function TEnumeratorRecord.MoveNext: Boolean;
- begin
- Result := fCurrent < fCount;
- if Result then
- Inc(fCurrent);
- end;
- { TEnumerableWithRecordEnumerator }
- function TEnumerableWithRecordEnumerator.GetEnumerator: TEnumeratorRecord;
- begin
- Result.fCount := fCount;
- Result.fCurrent := -1;
- end;
- { TEnumeratorObject }
- constructor TEnumeratorObject.Create(count: Integer);
- begin
- inherited Create;
- fCount := count;
- fCurrent := -1;
- end;
- function TEnumeratorObject.MoveNext: Boolean;
- begin
- Result := fCurrent < fCount;
- if Result then
- Inc(fCurrent);
- end;
- { TEnumerableWithObjectEnumerator }
- function TEnumerableWithObjectEnumerator.GetEnumerator: TEnumeratorObject;
- begin
- Result := TEnumeratorObject.Create(fCount);
- end;
- { TEnumeratorInterfacedObject }
- constructor TEnumeratorInterfacedObject.Create(count: Integer);
- begin
- inherited Create;
- fCount := count;
- fCurrent := -1;
- end;
- function TEnumeratorInterfacedObject.GetCurrent: Integer;
- begin
- Result := fCurrent;
- end;
- function TEnumeratorInterfacedObject.MoveNext: Boolean;
- begin
- Result := fCurrent < fCount;
- if Result then
- Inc(fCurrent);
- end;
- { TEnumerableWithInterfaceEnumerator }
- function TEnumerableWithInterfaceEnumerator.GetEnumerator: IEnumerator;
- begin
- Result := TEnumeratorInterfacedObject.Create(fCount);
- end;
- begin
- try
- Main;
- except
- on E: Exception do
- Writeln(E.ClassName, ': ', E.Message);
- end;
- Readln;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement