Advertisement
sglienke

Using generics for calculations

Jun 1st, 2016
190
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // modelled after this article http://www.codeproject.com/Articles/8531/Using-generics-for-calculations
  2. // tried the interface approach first but the Delphi compiler does not inline the call to the implementing class
  3. // but rather does a very imperformant call to the interface stub method
  4. // since we have virtual class methods in Delphi we can use them to declare an abstract class that is used as constraint
  5. // see https://blogs.msdn.microsoft.com/ericgu/2003/11/14/generics-algorithms/
  6.  
  7. program GenericsMadness;
  8.  
  9. {$APPTYPE CONSOLE}
  10. {$O+,W-}
  11.  
  12. uses
  13.   Diagnostics;
  14.  
  15. type
  16.   TCalculator<T> = class
  17.     class function Add(const a, b: T): T; virtual; abstract;
  18.   end;
  19.  
  20.   TLists<T;C:TCalculator<T>> = class
  21.   public
  22.     class function Sum(const list: TArray<T>): T; static;
  23.   end;
  24.  
  25.   TIntCalculator = class(TCalculator<Integer>)
  26.     class function Add(const a, b: Integer): Integer; override; final;
  27.   end;
  28.  
  29. { TLists<T, C> }
  30.  
  31. class function TLists<T,C>.Sum(const list: TArray<T>): T;
  32. var
  33.   i: Integer;
  34. begin
  35.   Result := Default(T);
  36.   for i := 0 to High(list) do
  37.     Result := C.Add(Result, list[i]);
  38. end;
  39.  
  40. { TIntCalculator }
  41.  
  42. class function TIntCalculator.Add(const a, b: Integer): Integer;
  43. begin
  44.   Result := a + b;
  45. end;
  46.  
  47. type
  48.   TIntLists = TLists<Integer,TIntCalculator>;
  49.  
  50. procedure Main;
  51. const COUNT = 10000000;
  52. var
  53.   list: TArray<Integer>;
  54.   i, n: Integer;
  55.   sum: Integer;
  56.   sw: TStopwatch;
  57. begin
  58.   list := [1, 2, 3, 4, 5, 6, 7, 8, 9];
  59.   sw := TStopwatch.StartNew;
  60.   for i := 1 to COUNT do
  61.   begin
  62.     sum := 0;
  63.     for n := 0 to High(list) do
  64.       sum := sum + list[n];
  65.   end;
  66.   Writeln(sum, ' ', sw.ElapsedMilliseconds);
  67.  
  68.   sw := TStopwatch.StartNew;
  69.   for i := 1 to COUNT do
  70.     sum := TIntLists.Sum(list);
  71.   Writeln(sum, ' ', sw.ElapsedMilliseconds);
  72. end;
  73.  
  74. begin
  75.   Main;
  76.   Readln;
  77. end.
Advertisement
RAW Paste Data Copied
Advertisement