Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];

Вниз

Производительность (оптимизация) функции   Найти похожие ветки 

 
pasha_golub ©   (2004-06-09 10:44) [0]

Имеем код:

type
 TForm1 = class(TForm)
    ...
 end;

MeasureFunc = procedure(ACanvas: TCanvas; ARect: TRect;
         FromColor, ToColor: TColor);
var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure VGradientFill(ACanvas: TCanvas; ARect: TRect;
         FromColor, ToColor: TColor);
var
 FC: array [0..3] of byte absolute FromColor;
 TC: array [0..3] of byte absolute ToColor;
 Steps, Y: integer;
 DR, DG, DB: integer;
begin
 Steps := ARect.Bottom - ARect.Top - 2;
 if Steps <= 0 then Exit;
 FromColor := ColorToRGB(FromColor);
 ToColor := ColorToRGB(ToColor);
 DR := TC[0] - FC[0];
 DG := TC[1] - FC[1];
 DB := TC[2] - FC[2];
 for Y := ARect.Top + 1  to ARect.Bottom - 1 do
   with ACanvas do
     begin
      MoveTo(ARect.Left, Y);
      Pen.Color := RGB(TC[0] - MulDiv(DR,Y,Steps),
                       TC[1] - MulDiv(DG,Y,Steps),
                       TC[2] - MulDiv(DB,Y,Steps));
      LineTo(ARect.Right,Y);
     end;
end;

procedure VGradientFill2(ACanvas: TCanvas; ARect: TRect;
         FromColor, ToColor: TColor);
var
 Steps, Y: integer;
 DR, DG, DB: integer;
begin
 Steps := ARect.Bottom - ARect.Top - 2;
 if Steps <= 0 then Exit;
 FromColor := ColorToRGB(FromColor);
 ToColor := ColorToRGB(ToColor);
 DR := GetRValue(ToColor) - GetRValue(FromColor);
 DG := GetGValue(ToColor) - GetGValue(FromColor);
 DB := GetBValue(ToColor) - GetBValue(FromColor);
 for Y := ARect.Top + 1  to ARect.Bottom - 1 do
   with ACanvas do
     begin
      MoveTo(ARect.Left, Y);
      Pen.Color := RGB(GetRValue(ToColor) - MulDiv(DR,Y,Steps),
                       GetGValue(ToColor) - MulDiv(DG,Y,Steps),
                       GetBValue(ToColor) - MulDiv(DB,Y,Steps));
      LineTo(ARect.Right,Y);
     end;
end;

procedure VGradientFill3(ACanvas: TCanvas; ARect: TRect;
         FromColor, ToColor: TColor);
var
 Steps, Y: integer;
 DR, DG, DB: integer;
 TR,TG,TB:byte;
begin
 Steps := ARect.Bottom - ARect.Top - 2;
 if Steps <= 0 then Exit;
 FromColor := ColorToRGB(FromColor);
 ToColor := ColorToRGB(ToColor);
 TR := GetRValue(ToColor);
 TG := GetGValue(ToColor);
 TB := GetBValue(ToColor);
 DR := TR - GetRValue(FromColor);
 DG := TG - GetGValue(FromColor);
 DB := TB - GetBValue(FromColor);
 for Y := ARect.Top + 1  to ARect.Bottom - 1 do
   with ACanvas do
     begin
      MoveTo(ARect.Left, Y);
      Pen.Color := RGB(TR - MulDiv(DR,Y,Steps),
                       TG - MulDiv(DG,Y,Steps),
                       TB - MulDiv(DB,Y,Steps));
      LineTo(ARect.Right,Y);
     end;
end;

function Measure(MF: MeasureFunc):int64;
var i:integer;
begin
 SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
 Result := GetTickCount;
 for i:=1 to 10000 do
  with Form1 do
   MF(Canvas,ClientRect,i,0);
 Result := GetTickCount - Result;
 SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_NORMAL);
end;

procedure TForm1.Button1Click(Sender: TObject);
var s :string;
begin
 FmtStr(S,"1:%d; 2:%d; 3:%d",[Measure(@VGradientFill),Measure(@VGradientFill2),Measure(@VGradientFill3)]);
 ShowMessage(S);
end;

end.


Итак, три реализации градентной заливки. Здесь я не хочу обсуждать другую реализацию алгоритма, а хочу заострить внимание на некоторых мелочах.

А именно.
1 функция: доступ к каждому компоненту цвета реализован через совместный доступ к памяти (директива absolute)
2 функция: доступ к каждому компоненту цвета реализован через существующие для этого функции (GetXValue), по сути через shr&shl
3 функция: тоже самое, что и вторая, но используются вспомогательные локальные переменные (TR,TG,TB)

Результаты:
1) 30544
2) 30798
3) 46199

Вопросы:
1. Могу ошибаться, но кто-то заявлял, что работа через absolute медленнее аналогичных. Про небезопасность кода и предупреждения компилятора я знаю, сейчас не про это. Так вот, это ошибка эксперимента или как?

2. Почему 3 функция так значительно отстает от 2? Ведь наскоко я понимаю доступ к локальным переменным осуществляется быстрее чем получение результатов функций (в данном примере GetXValue)

3. Если все-таки работа через absolute быстрее чем со сдвигами, почему же много людей так неохотно использовали (в связи с грядущим .НЕТ, я понимаю, что это небезопасно) эту гибкую систему?

Фух, спасибо за внимание.


 
pasha_golub ©   (2004-06-09 10:45) [1]

Прошу простить за путаницу в терминах, конечно речь идет о процедурах. :-)


 
MBo ©   (2004-06-09 12:34) [2]

1. у меня время одинаковое
2. 96% процента времени занимает вывод графики ;)


 
pasha_golub ©   (2004-06-09 12:38) [3]

1. у меня время одинаковое
Хм, вот те на. Что совсем одинаковое? :-)

2. 96% процента времени занимает вывод графики ;)
Кто ж спорит? :-)


 
MBo ©   (2004-06-09 12:44) [4]

>Что совсем одинаковое? :-)
Да, в пределах погрешности (полпроцента)

>96% процента времени занимает вывод графики ;)
В частности, изменение цвета пера (Pen.Color := ) - более половины времени работы программы.

>Кто ж спорит? :-)
Так сделай тест разумнее...


 
Daniel_   (2004-06-09 13:22) [5]

MBo ©  
А можно глупый, наверное, вопрос?

Каким образом вы узнаете какую долю времени выполняется каждая операция?


 
pasha_golub ©   (2004-06-09 13:24) [6]

Изменил код процедур:

procedure VGradientFill(ACanvas: TCanvas; ARect: TRect;
         FromColor, ToColor: TColor; var Res:TColor);
var
 FC: array [0..3] of byte absolute FromColor;
 TC: array [0..3] of byte absolute ToColor;
 Steps, Y: integer;
 DR, DG, DB: integer;
begin
 Steps := ARect.Bottom - ARect.Top - 2;
 if Steps <= 0 then Exit;
 FromColor := ColorToRGB(FromColor);
 ToColor := ColorToRGB(ToColor);
 DR := TC[0] - FC[0];
 DG := TC[1] - FC[1];
 DB := TC[2] - FC[2];
 for Y := ARect.Top + 1  to ARect.Bottom - 1 do
   with ACanvas do
     begin
      MoveTo(ARect.Left, Y);
      Res := RGB(TC[0] - MulDiv(DR,Y,Steps),
                TC[1] - MulDiv(DG,Y,Steps),
                TC[2] - MulDiv(DB,Y,Steps));
      //LineTo(ARect.Right,Y);
     end;
end;


В результате на 10000 итерациях:
1. 3810
2. 3959
3. 3815


 
MBo ©   (2004-06-09 13:27) [7]

>Daniel_
с помощью профайлера


 
pasha_golub ©   (2004-06-09 13:28) [8]

Daniel_   (09.06.04 13:22) [5]
Профайлером скорее всего.


 
pasha_golub ©   (2004-06-09 13:28) [9]

Удалено модератором
Примечание: Дубль


 
MBo ©   (2004-06-09 13:32) [10]

>pasha_golub ©   (09.06.04 13:24) [6]
А оптимизатор не удаляет строку:
Res := RGB(TC[0] - MulDiv(DR,Y,Steps),
               TC[1] - MulDiv(DG,Y,Steps),
               TC[2] - MulDiv(DB,Y,Steps));
?
может, завести глобальную переменную dummy, делать, например, dummy:=Res xor dummy, в конце вывести ее значение...


 
pasha_golub ©   (2004-06-09 13:33) [11]

Опять я прогнал. Забыл убрать Canvas.MoveTo:

procedure VGradientFill(ACanvas: TCanvas; ARect: TRect;
         FromColor, ToColor: TColor; var Res:TColor);
var
 FC: array [0..3] of byte absolute FromColor;
 TC: array [0..3] of byte absolute ToColor;
 Steps, Y: integer;
 DR, DG, DB: integer;
begin
 Steps := ARect.Bottom - ARect.Top - 2;
 if Steps <= 0 then Exit;
 FromColor := ColorToRGB(FromColor);
 ToColor := ColorToRGB(ToColor);
 DR := TC[0] - FC[0];
 DG := TC[1] - FC[1];
 DB := TC[2] - FC[2];
 for Y := ARect.Top + 1  to ARect.Bottom - 1 do
   with ACanvas do
     begin
      //MoveTo(ARect.Left, Y);
      Res{Brush.Color} := RGB(TC[0] - MulDiv(DR,Y,Steps),
                       TC[1] - MulDiv(DG,Y,Steps),
                       TC[2] - MulDiv(DB,Y,Steps));
      //LineTo(ARect.Right,Y);
     end;
end;

В таком же духе и другие процедуры. Получил на 10000 итерациях:
1. 1854
2. 2001
3. 1846


 
pasha_golub ©   (2004-06-09 13:36) [12]

MBo ©   (09.06.04 13:32) [10]
Нет, не удаляет. Res - это ж вар-параметр


 
Daniel_   (2004-06-09 14:37) [13]

> с помощью профайлера
> Профайлером скорее всего.

 Спасибо, пошел выбирать. Их, оказывается, много.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.105 c
14-1086548776
Undert
2004-06-06 23:06
2004.06.27
НЕ могу остановится !!! щас умру ...


11-1076153158
Ал
2004-02-07 14:25
2004.06.27
Не могу загрузить Bitmap из ресурса


14-1086940194
}|{yk
2004-06-11 11:49
2004.06.27
Презумпция невиновности в отношении публичных особ


14-1086852593
Pro
2004-06-10 11:29
2004.06.27
Нужна прога типа Диспетчер Задач


14-1086789420
Terminator
2004-06-09 17:57
2004.06.27
Где получить кредит?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский