Главная страница
    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.52 MB
Время: 0.041 c
15-1137394603
Nic
2006-01-16 09:56
2006.02.12
Чё-то с погодой не то...


15-1137442466
Гарри Поттер
2006-01-16 23:14
2006.02.12
Рисовалки


6-1131143339
Sysanin
2005-11-05 01:28
2006.02.12
ServerSocket ошибка при отправке


2-1138020724
md
2006-01-23 15:52
2006.02.12
Распечатать


2-1138220852
diwwww
2006-01-25 23:27
2006.02.12
через интернет набивать данные в dbf-файл IIS, ASP





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский