# Using generics for calculations

Jun 1st, 2016
190
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
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.
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
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;