Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.12;
Скачать: CL | DM;

Вниз

Советы по оптимизации - 1   Найти похожие ветки 

 
иосиф   (2006-01-11 07:30) [0]

Прочитал статью "Написание оптимального кода Delphi" она меня несколько смутила, да и мастера о ней отзываются не особо. Может быть действительно мастера поделятся своим опытом, дадут советы в плане оптимизации критичных по времени участков кода.

Вот к примеру стоит задача в один из методов (который буквально "постоянно" вызывается) приходит ряд параметров связанных с фильтрацией, последний же параметр передается по ссылку, чтобы подтвердить или опровергнуть фильтрацию. Как лучше организовывать подобную фильтрацию изнутри:


procedure TfrmMain.TestFilter(
 const Params: TSomeParams; var Filtered: Boolean);
begin
{ отлов объектов одного типа }
if Params.OType=otType1 then
begin
 if GetInfoObj<>-1 then
 begin
  if SomeData>=OtherData then Filtered:=False else Filtered:=True;
 end;
end;
{ отлов границ районов }
if Params.OType=otType2 then
begin
 if GetInfoObj<>2 then
 begin
  if SomeData>=OtherData then Filtered:=False else Filtered:=True;
 end;
end;
end;


Код приведен в общем виде. Интересно что лучше здесь применять - набор if инструкций, сделать все большим case, каким образом лучше организовывать последовательность if"ов и т.д.

з.ы. Хотелось бы все-таки что-то типа статьи, но оформленной в виде форуме нашими же мастерами. Среди них ведь есть люди, опыт которых не вызывает сомнений, а у многих есть желание подучиться ) может стоило и в потрепаться запостить...


 
Владислав ©   (2006-01-11 07:44) [1]

Так для этого профайлеры существуют.
Чего гадать, как лучше if"ы разместить, если проблема в другом месте может быть?


 
MBo ©   (2006-01-11 07:52) [2]

По приведенному фрагменту нельзя дать серьезных рекомендаций.
Неясно, много ли в реальном коде вариантов параметров, что делает GetInfoObj, каково будет значение Filtered при невыполнении условий if GetInfoObj и т.д.

P.S.
Эту строчку
>if SomeData>=OtherData then Filtered:=False else Filtered:=True;
лучше записать так:
Filtered := SomeData < OtherData;


 
иосиф   (2006-01-11 08:04) [3]

Владислав ©   (11.01.06 07:44) [1]
какой профайлер посоветуете под Delphi7? есть QATime, но он не бесплатен =( в основном натыкался на толковые memchecker"ы, но не на профайлеры (

MBo ©   (11.01.06 07:52) [2]
я понимаю приведенный код ужасен в плане описания ситуации. хотелось бы услышать общие напутствия ) что мол если таки то условия, то лучше бы сделать так, иначе вот так =)

данный обработчик может постепенно расти в объеме, добавляя новые условия фильтраций:


procedure TfrmMain.TestFilter(
 const SomeParams: TSomeParams; var Filtered: Boolean);
var
FParam: Integer;
begin
{ отлов объекта 1 }
if SomeParams.OType=otType1 then
begin
 FParam:=Integer(SomeParams.Detailed^);
 if FParam<>-1 then
  Filtered:=FParam<SomeObject.FParam;
end;
{ отлов объекта 2 }
if SomeParams.OType=otType2 then
begin
 if SomeParams.ID=frmMain.CurrentID then
  Filtered:=frmMain.ShowObject2 // boolean
 else
  Filtered:=False;
end;
end;


вот после преобразования так выглядит ) теоретически может быть расширен список фильтраций.


 
иосиф   (2006-01-11 08:20) [4]

если идти путем мастера MBo, то логично заменить:

 
 if SomeParams.ID=frmMain.CurrentID then
  Filtered:=frmMain.ShowObject2 // boolean
 else
  Filtered:=False;


на


 Filtered:=(SomeParams.ID=frmMain.CurrentID) AND frmMain.ShowObject2


но так падает читаемость кода, имхо. стоит ли оно того?


 
MBo ©   (2006-01-11 08:25) [5]

С точки зрения расширения и поддержания кода лучше, наверно, использовать принципы ООП - SomeParams превратить в объект с виртуальным методом фильтрации.

Если же оставить тип-запись, то многое зависит от количества вариантов параметров, по которым делается выбор. Если немного - case вполне достойно себя ведет.
В этой статье другой способ применен - большой case приводил к замедлению, и использованы указатели на функции (можно сделать массив процедурных переменных, индексированный параметром выбора):
http://www.delphimaster.ru/articles/pixels/index.html


 
MBo ©   (2006-01-11 08:27) [6]

>но так падает читаемость кода, имхо. стоит ли оно того?
Нет, тут не стоит. Первый вариант читается и понимается сразу же.


 
френк   (2006-01-11 08:54) [7]

MBo ©   (11.01.06 08:25) [5]
большущее спасибо!

з.ы.
ну почему бы таким отцам как MBo, Sha,  Leonid Troyanovsky (список можно продолжать, просто кого помню уже несколько лет) не написать замену сей статье по оптимизации? ;) прежде всего это интересно и позновательно!


 
Leonid Troyanovsky ©   (2006-01-11 09:10) [8]


> иосиф   (11.01.06 08:20) [4]

>  Filtered:=(SomeParams.ID=frmMain.CurrentID) AND frmMain.ShowObject2

> но так падает читаемость кода, имхо. стоит ли оно того?


Читаемость заметно улучшится, если не использовать frmMain.
Впрочем, это следует делать всегда.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-01-11 09:23) [9]


> иосиф   (11.01.06 08:04) [3]

>  хотелось бы услышать общие напутствия ) что мол если таки


Не очень понятно, почему возникла нужда в такой функции,
бо в приведенных примерах не используются комбинации из
двух и более параметров, и, сл-но, все эти проверки могут
выполнятся в функции, привязанной к каждому Params
(как процедурная ссылка в рекорде или метод объекта).

--
Regards, LVT.


 
Fay ©   (2006-01-11 09:44) [10]

Я, конечно, не из "список можно продолжать", но мне кажется, что Params.OType не может принимать несколько значений сразу. Т.о. :

if Params.OType=otType1 then
 begin
   if GetInfoObj<>-1 then
     Filtered := SomeData < OtherData;
 end
else if Params.OType=otType2 then
 begin
   if GetInfoObj <> 2 then
     Filtered := SomeData < OtherData;
 end;
end;


А ещё модет быть очень полезен case (otType1 - какого типа-то хоть?), т.е. :

case if Params.OType of
 otType1 : if GetInfoObj <> -1 then Filtered := SomeData < OtherData;
 otType2 : if GetInfoObj <> 2 then Filtered := SomeData < OtherData;
end;


Можно, в принципе, построить и такое

if ((Params.OType = otType1) and (GetInfoObj <> -1)) or (((Params.OType = otType2) and (GetInfoObj <> 2))) then
 Filtered := SomeData < OtherData;


, но это это может привести к двум вызовам GetInfoObj вместо одного.

2 иосиф   (11.01.06 8:20) [4]
Предложенное преобразование не является корректным.


 
Иосиф   (2006-01-11 09:59) [11]


Leonid Troyanovsky ©   (11.01.06 09:10) [8]
Читаемость заметно улучшится, если не использовать frmMain.


я комбинацией ряда элементов пытался показать что сие просто есть некий параметр булевского типа и они где-то выше он описан ) писал бы словами - мало кто бы понял, а так все поняли =) сам стараюсь избегать подобны
конструкций

Fay ©   (11.01.06 09:44) [10]
otType1/2 - ordinal ) enumeration может быть, я просто для примера.
первый пример с GetInfoObj я криво привел, прошу прощение.

я думаю что все что непосредственно касается сего примера можно считать закрытым, но очень бы хотелось чтобы наши мастера переписали сию статью с нуля =)


 
Leonid Troyanovsky ©   (2006-01-11 10:18) [12]


> Fay ©   (11.01.06 09:44) [10]

> 2 иосиф   (11.01.06 8:20) [4]
> Предложенное преобразование не является корректным.


Почему, собс-но?
Если $B+, то, вообще хорошо.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-01-11 10:21) [13]


> Leonid Troyanovsky ©   (11.01.06 10:18) [12]

> Если $B+, то, вообще хорошо.


Фу-ты. $B-.
Sorry.

--
Regards, LVT.


 
Владислав ©   (2006-01-11 11:41) [14]


> иосиф   (11.01.06 08:04) [3]
> какой профайлер посоветуете под Delphi7? есть QATime, но
> он не бесплатен =( в основном натыкался на толковые memchecker"ы,
>  но не на профайлеры (


Бесплатных не встречал. Может кто другой подскажет. Я AQTime использую.


 
Игорь Шевченко ©   (2006-01-11 12:45) [15]

gpprofile


 
иосиф   (2006-01-11 14:44) [16]

сорри очепятался, AQTime, конечно. Владислав, вы зарегистрированный пользователь AQTime? ;)

Игорь Шевченко ©   (11.01.06 12:45) [15]
спасибо, глянем-с


 
Владислав ©   (2006-01-11 14:49) [17]


> иосиф   (11.01.06 14:44) [16]


Лично я нет, но я его в личных целях не использую. :)
В [14] я имел ввиду, использую по работе.


 
Fay ©   (2006-01-11 20:44) [18]

2 Leonid Troyanovsky ©   (11.01.06 10:21) [12]
> Почему, собс-но?
Потому, что значение присваивается в любом случае. О оригинале не так.


 
palva ©   (2006-01-11 23:32) [19]

Вообще в статье есть ошибки. Например

for i:=0 to memo1.lines.count – 1 do...
 Delphi будет при каждой итерации вызывать метод count, вычитать из результата 1 и потом уже сверять.

Насколько я понимаю, выражение после "to" вычисляется один раз. Поэтому приведенному в статье совету по оптимизации такого кода лучше не следовать. Кроме того, count это не метод, а свойство.

Я писал автору письмо по этому поводу, но ответа не получил.


 
Fay ©   (2006-01-11 23:40) [20]

2 palva ©   (11.01.06 23:32) [19]
Это уже обсуждалось несколько раз 8)


 
palva ©   (2006-01-11 23:46) [21]

Ну и к чему пришли?


 
Fay ©   (2006-01-11 23:52) [22]

2 palva ©   (11.01.06 23:46) [21]
Главное - результат, а результат известен.


 
palva ©   (2006-01-12 00:00) [23]

> результат известен
Результат тот, что статья остается на сайте.


 
Leonid Troyanovsky ©   (2006-01-12 08:42) [24]


> Fay ©   (11.01.06 20:44) [18]

> > Почему, собс-но?
> Потому, что значение присваивается в любом случае. О оригинале
> не так.


В оригинале присвоение Filtered значения также происходит в любом
случае (третьего не дано).

Эквивалентность двух выражений проверяется путем сравнения
для обоих таблиц истинности (благо, варианта всего 4).
Т.е., корректность второго у меня не вызывает сомнений.

Если речь об оптимальности, то $B- дает то, что нужно, и, кроме того,
последовательный код предпочтительней ветвлений.

--
Regards, LVT.


 
Fay ©   (2006-01-12 09:08) [25]

2 Leonid Troyanovsky ©   (12.01.06 8:42) [24]

> В оригинале присвоение Filtered значения также происходит в любом
Согласен, это я не заметил else...



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

Текущий архив: 2006.02.12;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.044 c
15-1137944178
Kerk
2006-01-22 18:36
2006.02.12
650летие Самары


15-1137884122
ancot
2006-01-22 01:55
2006.02.12
Очередной генератор отчетов


4-1133257179
баклан
2005-11-29 12:39
2006.02.12
Нажатие кнопок, вводе текста и прочее...


2-1138266799
zorik
2006-01-26 12:13
2006.02.12
Как дописать StringList в текстовый файл?


2-1137933004
XeON
2006-01-22 15:30
2006.02.12
Побайтовое сравнение файлов