Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Оптимизация обновления базы данных на Accesse [D7, XP]


npu3pak ©   (2007-04-21 12:33:00) 

Доброго времени суток уважаемые!
Помогите оптимизировать нижеследующий код:

procedure RemainTime;
begin
count := 0;
time_now := HourOf(Now) * 60 + MinuteOf(Now);

with DataModule1.aqBase do
begin
DisableControls;
Open;
rc := RecordCount;
for i := 1 to rc do
 begin
 RecNo := i;
 buf1 := FieldByName('time_start').AsString;
 buf2 := FieldByName('time_end').AsString;
 if (buf1 <> '--:--') and (buf2 <> '--:--') then
  begin
  time_start := StrToInt(copy(buf1, 1, 2)) * 60 + StrToInt(copy(buf1, 4, 2));
  time_end := StrToInt(copy(buf2, 1, 2)) * 60 + StrToInt(copy(buf2, 4, 2));
  if time_start > time_end then time_end := time_end + 1440;
  if (FieldByName('time_remain').AsInteger > 0) and (FieldByName('time_remain').AsInteger < 5) then Inc(min5);
  if (FieldByName('time_remain').AsInteger <= 0) or (time_end - time_now <= 0) or (time_now > time_end) or (time_now < time_start) then
   begin
   end_session := end_session + IntToStr(i) + ', ';
   Edit;
   FieldByName('time_start').AsString := '--:--';
   FieldByName('time_time').AsString := '--:--';
   FieldByName('time_remain').AsInteger := 0;
   FieldByName('time_end').AsString := '--:--';
   FieldByName('price').AsInteger := 0;
   FieldByName('tarif').AsString := '';
   FieldByName('text').AsString := '';
   FieldByName('free').AsBoolean := true;
   Post;
   end
  else
   begin
   Edit;
   FieldByName('time_remain').AsInteger := time_end - time_now;
   Post;
   end;
  end;
 application.ProcessMessages;
 end;
Close;
EnableControls;
end;

if end_session <> '' then
if Length(end_session) > 2 then
 begin
 Delete(end_session, Length(end_session) - 1, 2);
 frmMain.mLog.Lines.Add('[' + TimeToStr(Now) + '] Окончан сеанс на компьютерах №: ' + end_session);
 ShowMessage('Время на компьютерах №: ' + end_session);
 end_session := '';
 end;

if min5 = 1 then frmMain.StatusBar1.Panels.Items[2].Text := 'Осталось меньше 5 минут на: ' + IntToStr(min5) + ' компьютере';
if min5 > 1 then frmMain.StatusBar1.Panels.Items[2].Text := 'Осталось меньше 5 минут на: ' + IntToStr(min5) + ' компьютерах';

DataModule1.aqShowData.Refresh;
end;

Тормоза страшные при кол-ве записей около 40! Эта процедура выполняется по таймеру, раз в 5 секунд. Увеличение интервала не дает ничего.


npu3pak   (2007-04-23 08:13:00) [1]


> Desdechado ©   (21.04.07 20:25) [2]
>
> При большом числе полей много времени отнимает FieldByName('xxx')
> в цикле. Лучше запихать указатели на поля в переменные до
> цикла, а в цикле обращаться уже наприямую к ним xxxValue:
> =xxx.AsString;

Дело в том, что поля всегда разные, т.е. они конечно могут повторяться, но это скорей исключение, чем правило.
> При большом числе полей много времени отнимает FieldByName('xxx')
Это понятно, но как еще можно считать данные, если строки разные?


npu3pak   (2007-04-23 08:06:00) [2]


> while not eof do
>  begin
>    ...
>    next;
>  end;

пробовал, результат тот же


> Вместо ProcessMessages не лучше ли использовать фоновый
> поток ?

это тема для меня пока мало изученная, т.к. я только месяц пишу программу :(


Desdechado   (2007-04-21 20:25:00) [3]

При большом числе полей много времени отнимает FieldByName('xxx') в цикле. Лучше запихать указатели на поля в переменные до цикла, а в цикле обращаться уже наприямую к ним xxxValue:=xxx.AsString;


MsGuns   (2007-04-21 19:57:00) [4]

Это не код, а триллер 8[]
Парочка вопросов:

а зачем хранить время строками и вообще так хитрозамучено с ним работать ?

зачем периодически дергать "сервер", если для уведомления о наступлениии на нем какого-то события можно "научить" его посылать сообщения клиенту-администратору.

Вместо ProcessMessages не лучше ли использовать фоновый поток ?

И еще вот это умиляет:

rc := RecordCount;
for i := 1 to rc do
begin
RecNo := i;


Почему нельзя без вычурностей:

while not eof do
 begin
   ...
   next;
 end;


И просто рекомендация.
Для диспетчерского интерфейса (если я верно уловил из приведенного кода) появляющиеся и тут же исчезающие сообщения неприемлимы.
Следует все диспетчируемые объекты (проессы) отображать в двух (трех)табличках - активные и завершенные (ждущие), причем по каждому объекту показывать :
- время старта
- продолжительность
- время окончания (для завершенных)
- резюме (выполняется, снят оператором, сбой ОС...)
- прочая информация об объекте

Критичные объекты (например те, которым осталось меньше 5 минут) можно выделять шрифтом или цветом)


Наверх

Титульная страница Поиск, карта сайта Написать письмо