프로그래밍/델파이

성능비교(Round, Trunc, Floor, MulDiv, 정수연산)

채윤아빠 2010. 1. 20. 17:14
728x90
반응형
화면에 표시하거나, 프린터에 인쇄를 할 경우 해상도에 따른 좌표 계산을 자주하게 됩니다. 좌표 계산을 위하여 위 정수연산을 하거나, Round, Trunc, Floor, MulDiv 등의 함수를 사용하게 됩니다. 그럼 이 방법들 중에서 가장 성능이 뛰어난 것은 무엇인지 갑자기 궁금하여 다음과 같이 간단한 소스로 성능을 실험해 보았습니다.
var
  i, nX, nOldX: integer;
  dwStart, dwEnd: DWORD;
begin
  nOldX := 50;
  dwStart := GetTickCount;
  for i := 0 to 10000000 do
    nX := Trunc(nOldX * 72. / 25.4);
  dwEnd := GetTickCount;
  Memo2.Lines.Add('Trunc(nOldX * 72. / 25.4) : nX = ' + IntToStr(nX) + '  ' + FormatFloat('#,##0', dwEnd - dwStart) + 'ms');

  dwStart := GetTickCount;
  for i := 0 to 10000000 do
    nX := Round(nOldX * 72. / 25.4);
  dwEnd := GetTickCount;
  Memo2.Lines.Add('Round(nOldX * 72. / 25.4) : nX = ' + IntToStr(nX) + '  ' + FormatFloat('#,##0', dwEnd - dwStart) + 'ms');

  dwStart := GetTickCount;
  for i := 0 to 10000000 do
    nX := Floor(nOldX * 72. / 25.4);
  dwEnd := GetTickCount;
  Memo2.Lines.Add('Floor(nOldX * 72. / 25.4) : nX = ' + IntToStr(nX) + '  ' + FormatFloat('#,##0', dwEnd - dwStart) + 'ms');

  dwStart := GetTickCount;
  for i := 0 to 10000000 do
    nX := MulDiv(nOldX, 720, 254);
  dwEnd := GetTickCount;
  Memo2.Lines.Add('MulDiv(nOldX, 720, 254) : nX = ' + IntToStr(nX) + '  ' + FormatFloat('#,##0', dwEnd - dwStart) + 'ms');

  dwStart := GetTickCount;
  for i := 0 to 10000000 do
    nX := nOldX * 720 div 254;
  dwEnd := GetTickCount;
  Memo2.Lines.Add('nOldX * 720 div 254 : nX = ' + IntToStr(nX) + '  ' + FormatFloat('#,##0', dwEnd - dwStart) + 'ms');
end;


위 소스와 같이 동일한 결과를 얻기 위한 연산을 약 1천만번 수행한 결과가 의외로 다음과 같이 나왔습니다.
Trunc(nOldX * 72. / 25.4) : nX = 141  250ms
Round(nOldX * 72. / 25.4) : nX = 142  125ms
Floor(nOldX * 72. / 25.4) : nX = 141  532ms
MulDiv(nOldX, 720, 254) : nX = 142  250ms
nOldX * 720 div 254 : nX = 141  203ms

위 결과에서 보듯이 Round 함수의 성능이 가장 뛰어났습니다. 당연히 정수연산이 가장 빠를 줄 알았는데 말이죠. 앞으로는 Round 함수를 애용해야 겠습니다.