Advertisement
sglienke

Enumerator Performance

Aug 31st, 2015
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 4.58 KB | None | 0 0
  1. program EnumeratorPerformance;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$OPTIMIZATION ON}
  5. {$STACKFRAMES OFF}
  6.  
  7. uses
  8.   Diagnostics,
  9.   SysUtils,
  10.   EnumeratorTypes in 'EnumeratorTypes.pas';
  11.  
  12. type
  13.   TEnumeratorRecord = record
  14.     fCount: Integer;
  15.     fCurrent: Integer;
  16.     function MoveNext: Boolean; inline; // no effect - compiler will not inline
  17.     property Current: Integer read fCurrent;
  18.   end;
  19.  
  20.   TEnumeratorObject = class
  21.   private
  22.     fCount: Integer;
  23.     fCurrent: Integer;
  24.   public
  25.     constructor Create(count: Integer);
  26.     function MoveNext: Boolean; inline;
  27.     property Current: Integer read fCurrent;
  28.   end;
  29.  
  30.   IEnumerator = interface
  31.     function GetCurrent: Integer;
  32.     function MoveNext: Boolean;
  33.     property Current: Integer read GetCurrent;
  34.   end;
  35.  
  36.   TEnumeratorInterfacedObject = class(TInterfacedObject, IEnumerator)
  37.   private
  38.     fCount: Integer;
  39.     fCurrent: Integer;
  40.   public
  41.     constructor Create(count: Integer);
  42.     function GetCurrent: Integer;
  43.     function MoveNext: Boolean;
  44.     property Current: Integer read GetCurrent;
  45.   end;
  46.  
  47.   TEnumerableBase = class
  48.   protected
  49.     fCount: Integer;
  50.   public
  51.     constructor Create(count: Integer);
  52.   end;
  53.  
  54.   TEnumerableWithRecordEnumerator = class(TEnumerableBase)
  55.     function GetEnumerator: TEnumeratorRecord;
  56.   end;
  57.  
  58.   TEnumerableWithObjectEnumerator = class(TEnumerableBase)
  59.     function GetEnumerator: TEnumeratorObject;
  60.   end;
  61.  
  62.   TEnumerableWithInterfaceEnumerator = class(TEnumerableBase)
  63.     function GetEnumerator: IEnumerator;
  64.   end;
  65.  
  66. const
  67.   RunCount = 10000;
  68.   ItemCount = 10000;
  69.  
  70. procedure TestEnumeratorRecord;
  71. var
  72.   e: TEnumerableWithRecordEnumerator;
  73.   n: Integer;
  74.  
  75.   procedure Enumerate;
  76.   var
  77.     i: Integer;
  78.   begin
  79.     for i in e do;
  80.   end;
  81.  
  82. begin
  83.   e := TEnumerableWithRecordEnumerator.Create(ItemCount);
  84.   try
  85.     for n := 1 to RunCount do
  86.       Enumerate;
  87.   finally
  88.     e.Free;
  89.   end;
  90. end;
  91.  
  92. procedure TestEnumeratorObject;
  93. var
  94.   e: TEnumerableWithObjectEnumerator;
  95.   n: Integer;
  96.  
  97.   procedure Enumerate;
  98.   var
  99.     i: Integer;
  100.   begin
  101.     for i in e do;
  102.   end;
  103.  
  104. begin
  105.   e := TEnumerableWithObjectEnumerator.Create(ItemCount);
  106.   try
  107.     for n := 1 to RunCount do
  108.       Enumerate;
  109.   finally
  110.     e.Free;
  111.   end;
  112. end;
  113.  
  114. procedure TestEnumeratorInterface;
  115. var
  116.   e: TEnumerableWithInterfaceEnumerator;
  117.   n: Integer;
  118.  
  119.   procedure Enumerate;
  120.   var
  121.     i: Integer;
  122.   begin
  123.     for i in e do;
  124.   end;
  125.  
  126. begin
  127.   e := TEnumerableWithInterfaceEnumerator.Create(ItemCount);
  128.   try
  129.     for n := 1 to RunCount do
  130.       Enumerate;
  131.   finally
  132.     e.Free;
  133.   end;
  134. end;
  135.  
  136. procedure Main;
  137. var
  138.   sw: TStopwatch;
  139. begin
  140.   sw := TStopwatch.StartNew;
  141.   TestEnumeratorRecord;
  142.   Writeln('record: ', sw.ElapsedMilliseconds);
  143.  
  144.   sw := TStopwatch.StartNew;
  145.   TestEnumeratorObject;
  146.   Writeln('object: ', sw.ElapsedMilliseconds);
  147.  
  148.   sw := TStopwatch.StartNew;
  149.   TestEnumeratorInterface;
  150.   Writeln('interface: ', sw.ElapsedMilliseconds);
  151. end;
  152.  
  153. { TEnumerableBase }
  154.  
  155. constructor TEnumerableBase.Create(count: Integer);
  156. begin
  157.   inherited Create;
  158.   fCount := count;
  159. end;
  160.  
  161. { TEnumeratorRecord }
  162.  
  163. function TEnumeratorRecord.MoveNext: Boolean;
  164. begin
  165.   Result := fCurrent < fCount;
  166.   if Result then
  167.     Inc(fCurrent);
  168. end;
  169.  
  170. { TEnumerableWithRecordEnumerator }
  171.  
  172. function TEnumerableWithRecordEnumerator.GetEnumerator: TEnumeratorRecord;
  173. begin
  174.   Result.fCount := fCount;
  175.   Result.fCurrent := -1;
  176. end;
  177.  
  178. { TEnumeratorObject }
  179.  
  180. constructor TEnumeratorObject.Create(count: Integer);
  181. begin
  182.   inherited Create;
  183.   fCount := count;
  184.   fCurrent := -1;
  185. end;
  186.  
  187. function TEnumeratorObject.MoveNext: Boolean;
  188. begin
  189.   Result := fCurrent < fCount;
  190.   if Result then
  191.     Inc(fCurrent);
  192. end;
  193.  
  194. { TEnumerableWithObjectEnumerator }
  195.  
  196. function TEnumerableWithObjectEnumerator.GetEnumerator: TEnumeratorObject;
  197. begin
  198.   Result := TEnumeratorObject.Create(fCount);
  199. end;
  200.  
  201. { TEnumeratorInterfacedObject }
  202.  
  203. constructor TEnumeratorInterfacedObject.Create(count: Integer);
  204. begin
  205.   inherited Create;
  206.   fCount := count;
  207.   fCurrent := -1;
  208. end;
  209.  
  210. function TEnumeratorInterfacedObject.GetCurrent: Integer;
  211. begin
  212.   Result := fCurrent;
  213. end;
  214.  
  215. function TEnumeratorInterfacedObject.MoveNext: Boolean;
  216. begin
  217.   Result := fCurrent < fCount;
  218.   if Result then
  219.     Inc(fCurrent);
  220. end;
  221.  
  222. { TEnumerableWithInterfaceEnumerator }
  223.  
  224. function TEnumerableWithInterfaceEnumerator.GetEnumerator: IEnumerator;
  225. begin
  226.   Result := TEnumeratorInterfacedObject.Create(fCount);
  227. end;
  228.  
  229. begin
  230.   try
  231.     Main;
  232.   except
  233.     on E: Exception do
  234.       Writeln(E.ClassName, ': ', E.Message);
  235.   end;
  236.   Readln;
  237. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement