On Fri, Jan 29, 2016 at 1:24 PM, Marco van de Voort <mar...@stack.nl> wrote:
> In our previous episode, Sven Barth said: > > > Interfaces are relatively slow. Not only because of the refcounting, > but > > > returning interfaces in a tight loop (e.g. to get the elements of an > > > enumeration) would be a new allocation each time. > > > > Note: the enumerator of a for-in is only fetched once before the loop, so > > it does not really matter whether it's an interface or record as long as > > the elements themselves aren't on demand allocated interfaces. > > The trouble is that you then have to avoid for-in for many potentially > small > iterations as in the hash case. Hm... that's my case. I have an object list that the key is an integer and the value is an object, ie a hash map. However, some years ago I got a problem using interfaces in an old draft that I made, so to fix the problem I chose abstract class instead of interface. I don't know if it is a compiler behaviour or something that I forgot, the test is: === begin code === ITest = interface ['{1DB8BD50-FCA2-40B3-B25B-A858DD206D26}'] procedure SetTest(ATest: ITest); end; TTest1 = class(TInterfacedObject, ITest) private FTest: ITest; public procedure SetTest(ATest: ITest); property Test: ITest read FTest write FTest; end; TTest2 = class(TInterfacedObject, ITest) private FTest: ITest; public procedure SetTest(ATest: ITest); property Test: ITest read FTest write FTest; end; ... procedure TTest1.SetTest(ATest: ITest); begin FTest := ATest; end; procedure TTest2.SetTest(ATest: ITest); begin FTest := ATest; end; procedure TForm1.Button1Click(Sender: TObject); var VTest1, VTest2: ITest; begin VTest1 := TTest1.Create; VTest2 := TTest1.Create; VTest1.SetTest(VTest2); VTest2.SetTest(VTest1); end; === end code === It throws some memory leaks, so to fix the problem I used abstract class: === begin code === TTest = class abstract public procedure SetTest(ATest: TTest); virtual; abstract; end; TTest1 = class(TTest) private FTest: TTest; public procedure SetTest(ATest: TTest); override; property Test: TTest read FTest write FTest; end; TTest2 = class(TTest) private FTest: TTest; public procedure SetTest(ATest: TTest); override; property Test: TTest read FTest write FTest; end; ... procedure TTest1.SetTest(ATest: TTest); begin FTest := ATest; end; procedure TTest2.SetTest(ATest: TTest); begin FTest := ATest; end; procedure TForm1.Button1Click(Sender: TObject); var VTest1, VTest2: TTest; begin VTest1 := TTest1.Create; VTest2 := TTest1.Create; VTest1.SetTest(VTest2); VTest2.SetTest(VTest1); VTest1.Free; VTest2.Free; end; === end code === However, I need to use the ARC feature in some occasions, and it seems that the better FPC entity that already implements that is the TInterfacedObject. :-/ -- Silvio Clécio
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel