title: Delphi Interface Performance Issue
body: <p>I have done some really serious refactoring of my text editor. Now there is much less code, and it is much easier to extend the component. I made rather heavy use of OO design, such as abstract classes and interfaces. However, I have noticed a few losses when it comes to performance. The issue is about reading a very large array of records. It is fast when everything happens inside the same object, but slow when done via an interface. I have made the tinyest program to illustrate the details:</p>
  
  <pre><code>unit Unit3;
  
  interface
  
  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs;
  
  const
    N = 10000000;
  
  type
    TRecord = record
      Val1, Val2, Val3, Val4: integer;
    end;
  
    TArrayOfRecord = array of TRecord;
  
    IMyInterface = interface
    ['{C0070757-2376-4A5B-AA4D-CA7EB058501A}']
      function GetArray: TArrayOfRecord;
      property Arr: TArrayOfRecord read GetArray;
    end;
  
    TMyObject = class(TComponent, IMyInterface)
    protected
      FArr: TArrayOfRecord;
    public
      procedure InitArr;
      function GetArray: TArrayOfRecord;
    end;
  
    TForm3 = class(TForm)
      procedure FormCreate(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
    end;
  
  var
    Form3: TForm3;
    MyObject: TMyObject;
  
  implementation
  
  {$R *.dfm}
  
  procedure TForm3.FormCreate(Sender: TObject);
  var
    i: Integer;
    v1, v2, f: Int64;
    MyInterface: IMyInterface;
  begin
  
    MyObject := TMyObject.Create(Self);
  
    try
      MyObject.InitArr;
  
      if not MyObject.GetInterface(IMyInterface, MyInterface) then
        raise Exception.Create('Note to self: Typo in the code');
  
      QueryPerformanceCounter(v1);
  
      // APPROACH 1: NO INTERFACE (FAST!)
    //  for i := 0 to high(MyObject.FArr) do
    //    if (MyObject.FArr[i].Val1 &lt; MyObject.FArr[i].Val2) or
    //         (MyObject.FArr[i].Val3 &lt; MyObject.FArr[i].Val4) then
    //      Tag := MyObject.FArr[i].Val1 + MyObject.FArr[i].Val2 - MyObject.FArr[i].Val3
    //               + MyObject.FArr[i].Val4;
      // END OF APPROACH 1
  
  
      // APPROACH 2: WITH INTERFACE (SLOW!)    
      for i := 0 to high(MyInterface.Arr) do
        if (MyInterface.Arr[i].Val1 &lt; MyInterface.Arr[i].Val2) or
             (MyInterface.Arr[i].Val3 &lt; MyInterface.Arr[i].Val4) then
          Tag := MyInterface.Arr[i].Val1 + MyInterface.Arr[i].Val2 - MyInterface.Arr[i].Val3
                   + MyInterface.Arr[i].Val4;
      // END OF APPROACH 2
  
      QueryPerformanceCounter(v2);
      QueryPerformanceFrequency(f);
      ShowMessage(FloatToStr((v2-v1) / f));
  
    finally
  
      MyInterface := nil;
      MyObject.Free;
  
    end;
  
  
  end;
  
  { TMyObject }
  
  function TMyObject.GetArray: TArrayOfRecord;
  begin
    result := FArr;
  end;
  
  procedure TMyObject.InitArr;
  var
    i: Integer;
  begin
    SetLength(FArr, N);
    for i := 0 to N - 1 do
      with FArr[i] do
      begin
        Val1 := Random(high(integer));
        Val2 := Random(high(integer));
        Val3 := Random(high(integer));
        Val4 := Random(high(integer));
      end;
  end;
  
  end.
  </code></pre>
  
  <p>When I read the data directly, I get times like 0.14 seconds. But when I go through the interface, it takes 1.06 seconds.</p>
  
  <p>Is there no way to achieve the same performance as before with this new design?</p>
  
  <p>I should mention that I tried to set <code>PArrayOfRecord = ^TArrayOfRecord</code> and redefined <code>IMyInterface.arr: PArrayOfRecord</code> and wrote <code>Arr^</code> etc in the <code>for</code> loop. This helped a lot; I then got 0.22 seconds. But it is still not good enough. And what makes it so slow to begin with?</p>