我已经对我的文本编辑器进行了一些非常重要的重构。现在有更少的代码,更容易扩展组件。我非常重视OO设计,比如抽象类和接口。不过,在表现方面,我注意到了一些损失。问题是阅读大量的记录。当所有事情发生在同一个对象内部时,速度很快,但是通过界面完成时速度很慢。我做了最小的程序来说明细节:
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 < MyObject.FArr[i].Val2) or // (MyObject.FArr[i].Val3 < 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 < MyInterface.Arr[i].Val2) or (MyInterface.Arr[i].Val3 < 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.
当我直接读取数据时,我得到0.14秒的时间。但是当我通过界面,需要1.06秒。
有没有办法实现与以前的新设计相同的表现?
我应该提到,我试图设置PArrayOfRecord = ^ TArrayOfRecord并重新定义IMyInterface.arr:PArrayOfRecord并在for循环中写入Arr ^等。这帮了很多然后我得到了0.22秒。但它还不够好。什么使它开始这么慢?