Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Оптимизация функции


Автор: aktuba 1.5.2007, 13:16
Есть такая функция:
Код

function CreateDate(dt: TDateTime; dy, dm, dw, dd, dh, dmin: Integer): TDateTime;
var
  y, m, d, h, min, s, ms: Word;
begin
  dt := IncMinute(dt, dmin);
  dt := IncHour(dt, dh);
  dt := IncDay(dt, dd + dw * 7);
  dt := IncMonth(dt, dm);
  dt := IncYear(dt, dy);
  DecodeDateTime(dt, y, m, d, h, min, s, ms);
  Result := EncodeDateTime(y, m, d, h, min, 0, 0);  
end;


Вкратце - задача функции добавить определенное кол-во лет(dy), месяцев(dm), недель(dw), дней(dd), часов(dh) и минут(dmin) к переданной дате. Еще в программе есть такой фрагмент:
Код

while ARec_Start <= ARec_End do
            begin
              Result := ((ARec_Start >= ADT_Start) and (ARec_Start <= ADT_End));
              if Result then Exit;
              ARec_Start := CreateDate(ARec_Start, tblRecordPeriod_Year.AsInteger,
                tblRecordPeriod_Month.AsInteger, tblRecordPeriod_Week.AsInteger,
                tblRecordPeriod_Day.AsInteger, tblRecordPeriod_Hour.AsInteger, tblRecordPeriod_Minut.AsInteger);
            end;


Задача этого фрагмента, проверить, попадает ли определенная дата и время в нужный диапазон. Все отлично работает, но "меня терзают смутные сомнения"... Пока записей мало и разница между проверяемой датой и диапазоном мала - все отлично, но в дальнейшем точно будет работать медленно. Например, если будет дата = 01.05.2007 с интервалом в 1 день (dd=1, все остальные параметры = 0), а диапазон равен 01.05.2057, то получается, что данная функция будет вызываться примерно 19000 раз. А если таких дат 100-200? А если не dd=1, а dmin?

Короче, очень хотелось бы как-то оптимизировать это, но сам никак не могу придумать. Может кто что подскажет? smile 

Автор: Snowy 1.5.2007, 13:34
Код

  result := IncMonth(dt, dy * 12 + dm) + dd + (dh  + dmin / 60) / 24;


Или по умному то же самое:
Код
  result := IncMonth(dt, dy * MonthsPerYear + dm) + dd + dh / HoursPerDay + dmin / MinsPerDay;


Добавлено через 6 минут и 29 секунд
Второй вариант выглядит умнее, но первый не требует подключения DateUtils.

Добавлено через 12 минут и 40 секунд
Цитата(aktuba @  1.5.2007,  13:16 Найти цитируемый пост)
Задача этого фрагмента, проверить, попадает ли определенная дата и время в нужный диапазон.
А зачем цикл?
Почему просто не проверить:
Код
  if (dt >= dt_start) and (dt <= dt_end) then ...
? Или я что-то не понял?

Автор: aktuba 1.5.2007, 14:03
Цитата

А зачем цикл?


Смотри, предположим есть дата: 01.05.2006 13:00, для которой прописано какое-то событие, которое должно выполняться еженедельно, т.е. 01.05.2006, 08.05.2006, 15.05.2006 и т.д. Теперь мне надо проверить, попадает ли это событие в диапазон от сегодня до послезавтра... Теперь нормально объяснил? Другого пути пока не вижу =((((

P.S.: счас заменю функцию на второй твой вариант, но мне кажется это не сильно поможет =((( Может еще какие идеи есть?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)