Форум: "Основная";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
ВнизGoto оптимален? Найти похожие ветки
← →
Sandman25 © (2004-06-08 12:12) [0]Добрый день.
Пишу код вродеwith DataSet do
begin
while not Eof do
begin
case Field1.Value of
1,
2:
;
3:
if Count1 > 3 then
begin
Next;
Continue;
end
else
Inc(Count1);
4:
if Count2 > 4 then
begin
Next;
Continue;
end
else
Inc(Count2);
else
begin
Next;
Continue;
end
end;
... обработка данных
Next;
end;
end;
Как видите, код неоптимален из-за повторяющегося фрагмента - Next;Continue. Как лучше всего от него избавиться? Меткой, флагом, вызовом локальной процедуры?
← →
Digitman © (2004-06-08 12:21) [1]with DataSet do
while not Eof do
try
case Field1.Value of
1, 2:;
3: if Count1 > 3 then Continue else Inc(Count1);
4: if Count2 > 4 then Continue else Inc(Count2);
end;
... обработка данных
finally
Next;
end;
← →
Sandman25 © (2004-06-08 12:31) [2][1] Digitman © (08.06.04 12:21)
Большое спасибо!
Записей мало (до 15), поэтому задержка из-за try-finally некритична.
← →
Anatoly Podgoretsky © (2004-06-08 12:45) [3]Это вообще лишнее
1, 2:;
Пустой оператор
← →
Sandman25 © (2004-06-08 12:47) [4][3] Anatoly Podgoretsky © (08.06.04 12:45)
У case есть ветвь else. См. [1].
← →
Sandman25 © (2004-06-08 12:47) [5]То есть не [1], а [0]
← →
Anatoly Podgoretsky © (2004-06-08 13:12) [6]Sandman25 © (08.06.04 12:47) [4]
Не обратил внимания, смотрел не на твой код, в товем нужно.
← →
MU © (2004-06-08 15:12) [7]with DataSet do
while not Eof do begin
case Field1.Value of
3: if Count1 <= then Inc(Count1);
4: if Count2 <= 4 then Inc(Count2);
end;
Next;
end;
← →
evvcom © (2004-06-08 15:33) [8]
> MU © (08.06.04 15:12) [7]
Не учел ...обработка данных. При той постановке задачи мой голос за Digitman. А вообще я бы пересмотрел такую постановку задачи. Не кажется она мне логичной, но это imho
← →
MU © (2004-06-08 15:44) [9]>>evvcom ©
Да-да, я это понял, сразу после... :(
← →
Sandman25 © (2004-06-08 15:44) [10][8] evvcom © (08.06.04 15:33)
Подготовка данных для печати документа.
Если поле равно 1 или 2, то это отец и мать - они печатаются всегда и их количество не превышает одного.
Если поле равно 3, то это супруга или супруг. Если поле равно 4, то дети. В отчет должны попадать не более 3 жен (мужей) и не более 4 детей. Прочие родственники в отчет не попадают. Теперь логично? :)
← →
DieHard (2004-06-08 16:23) [11]
Count1 = 0;
Count2 = 0;
with DataSet do
begin
while not Eof do
begin
case Field1.Value of
3:
Inc(Count1);
4:
Inc(Count2);
end;
if (Field1.Value in [1..4]) and (Count1 <= 3) and (Count2 <= 4) then
begin
... обработка данных
end;
Next;
end;
end;
← →
Sandman25 © (2004-06-08 16:27) [12][11] DieHard (08.06.04 16:23)
if (Field1.Value in [1..2]) or (Field1.Value = 3) and (Count1 <= 3) or (Field1.Value = 4) and (Count2 <= 4) then
Но не очень структурно проверять значение переменной более 1 раза ИМХО
← →
DieHard (2004-06-08 16:44) [13]
Count1 = 0;
Count2 = 0;
with DataSet do
begin
while not Eof do
begin
NeedProcessing := False;
case Field1.Value of
1, 2: NeedProcessing := True;
3:
Inc(Count1);
NeedProcessing := Count1 <= 3;
4:
Inc(Count2);
NeedProcessing := Count2 <= 4;
end;
if NeedProcessing then
begin
... обработка данных
end;
Next;
end;
end;
Лишняя переменная - это структурно? ;)
← →
Mim1 © (2004-06-08 16:50) [14][1] Digitman © (08.06.04 12:21)
[2] Sandman25 © (08.06.04 12:31)finally
Next;
end;
Чтото я не вижу смысла в этом коде. Какая разница на какой записи останется курсор при возникновении исключения.
← →
Sandman25 © (2004-06-08 16:52) [15][13] DieHard (08.06.04 16:44)
Вполне. Переделаю под Ваш вариант. Отсутствие else-секции в case очень полезно :)
← →
Плохиш (2004-06-08 16:53) [16]>Mim1 © (08.06.04 16:50) [14]
Там Continue стоит ;-)
← →
DieHard (2004-06-08 16:54) [17][14] Mim1
Исключения не будет, этого и не требуется, просто нужно, чтобы Next выполнился в любом случае, что и обеспечивает try ... finally ... end;
← →
Anatoly Podgoretsky © (2004-06-08 16:56) [18]Если речь идет о красоте это одно, а если оптимизация по скорости, то это бессмысленно в данном случае.
← →
MU © (2004-06-08 16:57) [19]with DataSet do
while not Eof do begin
case Field1.Value of
1,2:
3 : if Count1 <= then Inc(Count1);
4 : if Count2 <= 4 then Inc(Count2);
else begin
//......Обработка данных
end;
end;
Next;
end;
:))
← →
Sandman25 © (2004-06-08 17:03) [20]Остановился на следующем варианте:
RelatedIndex := clRelatedRelType.Value;
case RelatedIndex of
1, // отец
2: // мать
NeedsProcessing := True;
3: // супруг(и)
begin
Inc(MarriedCount);
// разрешаем до 3 супругов включительно
NeedsProcessing := MarriedCount <= 3;
RelatedIndex := 2 + MarriedCount; // от 3 до 5
end;
4: // дети
begin
Inc(ChildrenCount);
// разрешаем до 4 супругов включительно
NeedsProcessing := ChildrenCount > 4;
RelatedIndex := 5 + ChildrenCount // от 6 до 9
end
else
NeedsProcessing := False;
end;
if NeedsProcessing then
Решил при присвоении RelatedIndex внутри case не проверять NeedsProcessing.
← →
Игорь Шевченко © (2004-06-08 17:06) [21]Я бы так сделал, тоже, наверное, неоптимально:
procedure TForm1.FormCreate(Sender: TObject);
function NeedProcessing: Boolean;
begin
Result := (Field1.Value in [1,2]) or ((Field1.Value = 3) and Count1 < 3)
or ((Field1.Value = 4) and Count2 < 4);
end;
begin
with DataSet do begin
while not Eof do begin
if NeedProcessing then begin
if Field1.Value = 3 then
Inc(Count1)
else if Field1.Value = 4 then
Inc(Count2);
{ ... обработка данных }
end;
Next;
end;
end;
end;
← →
Sandman25 © (2004-06-08 17:11) [22]Доработанный вариант [21] Игорь Шевченко © (08.06.04 17:06)
procedure TForm1.FormCreate(Sender: TObject);
function NeedProcessing: Boolean;
begin
case Field1.Value of
1,2:
Result := True;
3:
Result := Count1 < 3;
4:
Result := Count2 < 4;
else
Result := False
end;
end;
begin
with DataSet do begin
while not Eof do begin
if NeedProcessing then begin
case Field1.Value of
3: Inc(Count1);
4: Inc(Count2);
end;
{ ... обработка данных }
end;
Next;
end;
end;
end;
← →
panov © (2004-06-08 17:16) [23]Непонятно, зачем усложнять?
begin
while not Eof do
begin
case Field1.Value of
3: if Count1<=3 then Inc(Count1);
4: if Count2<=4 then Inc(Count2);
else
begin
Next;
Continue;
end;
end;
... обработка данных
Next;
end;
end;
← →
Sandman25 © (2004-06-08 17:19) [24][23] panov © (08.06.04 17:16)
Не эквивалентно [0]
← →
Weber © (2004-06-08 17:20) [25]
> panov © (08.06.04 17:16) [23]
Вот именно, "дайте кусок вашего кода нам и через минуту вы не узнаете его!"
← →
panov © (2004-06-08 17:24) [26]>Sandman25 © (08.06.04 17:19) [24]
уг-)
достаточно 1 и 2 включить.
begin
while not Eof do
begin
case Field1.Value of
1,2: ;
3: if Count1<=3 then Inc(Count1);
4: if Count2<=4 then Inc(Count2);
else
begin
Next;
Continue;
end;
end;
... обработка данных
Next;
end;
end;
← →
panov © (2004-06-08 17:25) [27]>Sandman25 © (08.06.04 17:19) [24]
Кстати, а какие критерии оптимальности?
← →
Sandman25 © (2004-06-08 17:28) [28][26] panov © (08.06.04 17:24)
Все равно не соответствует. Не надо обрабатывать, если Count1 стала > 4 и т.д.
[27] panov © (08.06.04 17:25)
В первую очередь - структурность, во вторую - скорость. В третью - размер кода и данных :)
← →
panov © (2004-06-08 17:31) [29]>Sandman25 © (08.06.04 17:28) [28]
С критериями понятно-)
Тогда решения есть уже, и не одно-)
← →
Игорь Шевченко © (2004-06-08 17:33) [30]Sandman25 © (08.06.04 17:28)
Я руководствовался одним критерием - читабельность кода. И рекомендую всех руководствоваться им же :)
С этой точки зрения вариант Sandman25 © (08.06.04 17:11) [22]
выглядит более читабельным, чем мой.
← →
Sandman25 © (2004-06-08 17:34) [31][29] panov © (08.06.04 17:31)
Именно так. И [1], и [20] меня вполне устраивают. Все же продолжаю читать ветку - вдруг что-нибудь новое узнаю :)
← →
Anatoly Podgoretsky © (2004-06-08 17:36) [32]На скорость может внимания не обращать, оно ничтожно по отношению с остальным.
← →
panov © (2004-06-08 17:37) [33]>Игорь Шевченко © (08.06.04 17:33) [30]
Разве использование case дважды улучшает читабельность кода?
← →
Sandman25 © (2004-06-08 17:37) [34][30] Игорь Шевченко © (08.06.04 17:33)
Иногда читабельностью нужно пренебречь ради скорости. Простейший пример:with DataSet do
try
while not Eof do
begin
Edit;
...
Post;
Next;
end;
except
if State in dsEditModes then
Cancel;
raise;
end;
Читабельнее вызывать процедуру с try-except внутри, но try-except в цикле сильно затормозит работу.
← →
Sandman25 © (2004-06-08 17:38) [35][32] Anatoly Podgoretsky © (08.06.04 17:36)
В принципе согласен, но у меня это уже дело привычки :)
Раньше отвечал за скорость работы хранимых процедур
← →
panov © (2004-06-08 17:38) [36]К тому же, если в [0] видна вся структура вычмслений, то в [22], чтобы понять логику, нужно еще всмотреться пристально и напрячься.
← →
Verg © (2004-06-08 17:40) [37]Я бы добавил к коду:
> [1] Digitman © (08.06.04 12:21)
> with DataSet do
> while not Eof do
> try
> case Field1.Value of
> 1, 2:;
> 3: if Count1 > 3 then Continue else Inc(Count1);
> 4: if Count2 > 4 then Continue else Inc(Count2);
else
continue;
> end;
> ... обработка данных
> finally
> Next;
> end;
...и успокоился бы. Вызов кодом самой же программы цепочки (чек) finally - исчезающе малое время по сравнению с Next у DataSet
← →
Игорь Шевченко © (2004-06-08 17:41) [38]
> но try-except в цикле сильно затормозит работу.
По какой причине ?
panov © (08.06.04 17:38)
> К тому же, если в [0] видна вся структура вычмслений,
В [0] ее как раз и не видно
← →
Sandman25 © (2004-06-08 17:52) [39]Только что сделал через метку. Стошнило от одного только вида, хотя по скорости и было оптимально.
Попробовал сделать через локальную процедуру. Вроде ничего смотрится.case RelatedIndex of
1, // отец
2: // мать
PrintRelated;
3: // супруг(и)
begin
Inc(MarriedCount);
// разрешаем до 3 супругов включительно
if MarriedCount <= 3 then
begin
RelatedIndex := 2 + MarriedCount; // от 3 до 5
PrintRelated;
end;
end;
4: // дети
begin
Inc(ChildrenCount);
// разрешаем до 4 детей включительно
if ChildrenCount > 4 then
begin
RelatedIndex := 5 + ChildrenCount; // от 6 до 9
PrintRelated;
end;
end
end;
clRelated.Next;
← →
Sandman25 © (2004-06-08 17:54) [40][38] Игорь Шевченко © (08.06.04 17:41)
По причине большого числа дополнительных ассемблерных команд для обеспечения try-except.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.029 c