상세 컨텐츠

본문 제목

인터페이스 릴레이에서 최대한 메소드 호출 시간 절약하기

프로그래밍/Delphi

by ryujt 2012. 7. 3. 00:01

본문

지난 번 포스트에서 "인터페이스 릴레이"라는 주제를 다룬 적이 있습니다.  특정 객체가 다른 객체의 메소드를 위임 받아 실행하기 때문에 메소드가 다른 메소드를 호출하고 리턴을 돌려주는 일만 담당하는 경우가 되겠습니다.


이러한 경우 최대한 메소드 호출 시간을 절약하기 위해서 다음과 같이 뻘짓을 해봤습니다 ^^;  


1억번 반복에 약 500 ms를 절약 할 수 있었습니다.  테스트 환경은 인텔 듀얼 코어 2.6GHz 노트북입니다.


[소스]

unit _fmMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TFirstTest = class (TComponent)
  private
    FNO : integer;
  public
    procedure DoSomething;
  published
    property No : integer read FNo;
  end;

  TSecondTest = class
  private
    FTest : TFirstTest;
  public
    constructor Create;
    destructor Destroy; override;

    procedure DoSomething;
  end;

  TThirdTest = class
  private
    FTest : TFirstTest;
  public
    constructor Create;
    destructor Destroy; override;

    var DoSomething : procedure of object;
  end;

  TfmMain = class(TForm)
    btTest: TButton;
    procedure btTestClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FFirstTest : TFirstTest;
    FSecondTest : TSecondTest;
    FThirdTest : TThirdTest;
  public
  end;

var
  fmMain: TfmMain;

implementation

uses
  MMTimer;

{ TFirstTest }

procedure TFirstTest.DoSomething;
begin
  FNo := FNo + 1;
end;

{ TSecondTest }

constructor TSecondTest.Create;
begin
  inherited;

  FTest := TFirstTest.Create(nil);
end;

destructor TSecondTest.Destroy;
begin
  FreeAndNil(FTest);

  inherited;
end;

procedure TSecondTest.DoSomething;
begin
  FTest.DoSomething;
end;

{ TThirdTest }

constructor TThirdTest.Create;
begin
  inherited;

  FTest := TFirstTest.Create(nil);
  DoSomething := FTest.DoSomething;
end;

destructor TThirdTest.Destroy;
begin
  FreeAndNil(FTest);

  inherited;
end;

{$R *.dfm}

procedure TfmMain.btTestClick(Sender: TObject);
var
  Loop1: Integer;
  Loop2: Integer;
  Tick : DWord;
begin
  Tick := MMGetTickCount;

  for Loop1 := 1 to 10000 do
//  for Loop2 := 1 to 10000 do FTest.DoSomething;  // 559 ms
//  for Loop2 := 1 to 10000 do FSecondTest.DoSomething;  // 829 ms
  for Loop2 := 1 to 10000 do FThirdTest.DoSomething;  // 580 ms

  Caption := IntToStr(MMGetTickCount - Tick);
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  MMInitialize;

  FFirstTest := TFirstTest.Create(nil);
  FSecondTest := TSecondTest.Create;
  FThirdTest := TThirdTest.Create;
end;

end.


관련글 더보기