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

Вниз

как реализовать СЕКУНДОМЕР?   Найти похожие ветки 

 
Idiliya ©   (2004-05-24 09:23) [0]

Здравствуйте, господа хорошие!
Необходимо реализовать Секундомер.
Как отобразить в лабельке сколько времени потребовалось на выполнение операции от запуска до паузы, понятно: просто запомнить текущее время в момент запуска, а затем вычесть его из текущего времени останова. Но как сделать, чтобы в Lable отображался ежесекундный прирост, как, собственно, в секундомере, чтобы к тому же сам "секундомер" не очень замедлял процесс расчетов?
Секундомер нужен, чтобы сравнить скорость расчетов двух разных методов по мат.физике.
Если актуально, то добавлю, что методы расчитываются в нитке (Thread).


 
Думкин ©   (2004-05-24 09:26) [1]

Или с помощью таймера, или в потоке.


 
Idiliya ©   (2004-05-24 09:46) [2]

В потоке, это не совсем точно.
Я считаю шаги в потоке, т.е. попросту сколько ниток прошло.
Программа работает либо с одним методом, либо с другим по выбору.
На каждом шаге нитки оба метода должны давать ОДИНАКОВЫЕ результаты расчетов. Они их дают. Но необходимо показать, что, например, метод FFT быстрее приходит к 500 шагу, чем метод SOR к этому же шагу (а соответственно, и результату).
Поэтому здесь именно время играет роль. Надо замерять.
С помощью таймера не знаю как это реализовать.
Не работала с таймером.
Знаю, как можно его включить, и что можно задать что-нибудь на событие OnTimer. Но что? Как правильно работать со временем? Чтобы выводились секунды и минуты. Часы не актуально: ни один чел не выдержит тестировать мои методы больше 40 минут :)


 
ega23 ©   (2004-05-24 09:51) [3]

GetTickCount попробуй...


 
SammIk ©   (2004-05-24 10:00) [4]

tmp:=GetTickCount;
вачисления
tmp:=(GetTickCount-tmp)/1000;Скорость выполнения блока в секундах


 
SammIk ©   (2004-05-24 10:01) [5]

Удалено модератором
Примечание: Дубль


 
SammIk ©   (2004-05-24 10:03) [6]

Удалено модератором
Примечание: Дубль


 
ega23 ©   (2004-05-24 10:07) [7]

SammIk ©   (24.05.04 10:00) [4]

Может лучше for i:=1 to 3 do ... чем 3 раза GetTickCount брать? :о)


 
SammIk ©   (2004-05-24 10:16) [8]

Не усмотрел, тогда лучше в цикле будет))ИМХО
У кого какие соображения?


 
Думкин ©   (2004-05-24 10:18) [9]

> Idiliya ©   (24.05.04 09:46) [2]
> В потоке, это не совсем точно.

Извините, но я, видимо, плохо понимаю вашу проблему. Почему в потоке запустить вывод времени никак?


 
EXE   (2004-05-24 10:20) [10]

Можно, как один из вариантов,
Кинь на форму Timer
И на событии Ontimer

edit1.Text := timetostr(time);

установи
timer1.Interval := 1000;

Включение таймера
Timer1.Enabled := true;

Выключение таймера
Timer1.Enabled := False;


 
SammIk ©   (2004-05-24 10:26) [11]

И как минимум 3-4 раза стоет это дело повторить.
Ведь фортень многозадачная система и какои-нить левыи процесс
захочит повыполнятся и один из потоков будет не заслуженно
назван медленным и все такое.
Совет приоритет повынк сделаи, как для потоков, так и для
процесса, да не сильно увлекаися.))


 
nejest   (2004-05-24 10:53) [12]

Вот пример обработчика таймера:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if(st=0) then // Проверка запущен, ли секундомер
begin
 sec:=sec+1; //Увиличение числа секунд
  if(sec=60) then // Наступила, ли следующая минута?
   begin
    sec:=0; // обнуление секунд
    min:=min+1; //Увиличение числа минут
   end;
  if(sec<10) then
   label1.Caption:=IntToStr(min)+": 0"+IntToStr(sec)
  else
   label1.Caption:=IntToStr(min)+":"+IntToStr(sec);
 end;
end;


 
ega23 ©   (2004-05-24 10:59) [13]

nejest   (24.05.04 10:53) [12]

КРУТО!!!!!
А часы куда дел? Сутки? Недели?


 
nejest   (2004-05-24 13:29) [14]

2 ega23 [13]
В моём случае нужно время в минутах. Я выложил кусок своей программы, и мне было лень её переделывать, добавляя часы. Тем более, что часы сутки и недели можно добавить по аналогии с минутами.
P.S. Те, кто не могут добавить по аналогии см. ниже:
измените порверку следующей минуты:  
if(sec=60) then // Наступила, ли следующая минута?
  begin
   sec:=0; // обнуление секунд
   min:=min+1; //Увиличение числа минут
    if(min=60) then
     begin
      min:=0;  
      hour:=hour+1;
       if(hour=24)then
        begin
         hour:=0;
         day:=day+1;
        end;
     end;
  end;
P.P.S. Можно реализовать в виде функций: IncSec, IncMin, IncHour;


 
ega23 ©   (2004-05-24 13:36) [15]

2 nejest   (24.05.04 13:29) [14]
Ты ещё про IncDay забыл. Где-то тут в Кладовке была, искать лень. Но код себе я сохранил:

function TfmMain.IncDay(const DateTime: TDateTime;  NumberOfDays: Integer): TDateTime;
{Функция предназначена для изменения даты (DateTime) путем добавления  количества дней (NumberOfDays). Значение NumberOfDays может быть отрицательным.}
var
 Y, M, D, CountDays: Word;
 N: Integer;
 Sign, NoBreak: Boolean;
begin
 Sign := NumberOfDays >= 0;
 DecodeDate(DateTime, Y, M, D);
 N := NumberOfDays;
 NoBreak := True;
 if Sign then   //Прибавить
 begin
   while(NoBreak) do
   begin //Количество дней в месяце
     CountDays := MonthDays[IsLeapYear(Y), M];
     if (N + D) <= CountDays then //Если в пределах данного месяца
     begin
       Inc(D, N);
       NoBreak := False;
     end
     else
     begin
       if M < 12 then
         Inc(M, 1)
       else
       begin
         M := 1;
         Inc(Y, 1);
       end;
       N := N - (CountDays - D);
       D := 0;
     end;
   end;
 end
 else  //Отнять
 begin
   N := -N;
   while(NoBreak) do
   begin
     if D > N then  //Если в пределах данного месяца
     begin
       Dec(D, N);
       NoBreak := False;
     end
     else
     begin
       if M > 1 then
         Dec(M, 1)
       else
       begin
         M := 12;
         Dec(Y, 1);
       end;
       //Количество дней в месяце
       CountDays := MonthDays[IsLeapYear(Y), M];
       N := N - D;
       D := CountDays;
     end;
   end;  
 end;
 Result := EncodeDate(Y, M, D);
 //Установить время из старой даты
 ReplaceTime(Result, DateTime);
end;

З.Ы. Это я издеваюсь, потому что с женой вчера поругался. Не обижайся. А что касается твоего таймера, то точно работать он не будет. Проверь сам. Запусти его вместе с Касперским. Или дефрагментацией диска.


 
nejest   (2004-05-24 13:47) [16]

2 ega23 ©   (24.05.04 13:36) [15]
У меня программа работала. И даже, передавала результаты в Эксель.


 
ega23 ©   (2004-05-24 13:52) [17]

У меня программа работала. И даже, передавала результаты в Эксель.

Работать будет. Но не точно. Реально таймер не раз в секунду будет срабатывать, а раз в "секунду с небольшим". Если нужен набор статистики, то данные буду неточными.


 
Кщд   (2004-05-24 13:55) [18]

nejest   (24.05.04 13:47) [16]
сейчас придет кто-нибудь злобный, и он не будет глумиться над Вами так мягко, как господин ega23 © :)


 
Anatoly Podgoretsky ©   (2004-05-24 14:15) [19]

nejest   (24.05.04 10:53) [12]
И получишь управление в таймере скажем через три минуты, а прибавляешь только одну секунду. Таймер не для отсчетов времени и для периодического прерывания программы, где интревал +- километр.


 
Idiliya ©   (2004-05-25 09:35) [20]

Ну, началось: недели, километры...
Я ведь только Секундомер просила :)
Реализовала здесь кое-что, посмотрите:

На кнопке запуска расчетов (запускается один раз) добавила следующий код
 g_tmpTime := Time;
 Timer1.Enabled := TRUE;


Затем в свойствах Таймера поставила интервал 1000, а в событии OnTime Таймера вставила код
 g_tmpTime := Time - g_tmpTime;
 Label3.Caption := FormatDateTime("nn:ss:zz",g_tmpTime);


ИМХО должно было бы работать безотказно.
НО! Первую половину секунды он показывает настоящее время, вторую - то, что хотелось, и так по очереди в секунду отображается два значения: нежелательное и желательное.
Откуда он берет g_tmpTime = Time, если присвоение было всего один раз вначале? Моя g_tmpTime - глобальная переменная.


 
ega23 ©   (2004-05-25 09:59) [21]

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


 
ega23 ©   (2004-05-25 10:01) [22]

Виноват, невнимательно прочитал. Я бы вместо Time полльзовался GetTickCount.


 
Anatoly Podgoretsky ©   (2004-05-25 10:21) [23]

Весьма странная конструкция  g_tmpTime := Time - g_tmpTime; и можешь ли ты объяснить что она делает, кроме пинг-понга?
Наверно надо так

Label3.Caption := TimeToStr(Now - StartTime);

Вот это будет показывать бег секунд.


 
Idiliya ©   (2004-05-25 23:13) [24]


> Anatoly Podgoretsky ©   (25.05.04 10:21) [23]

Милый Анатолий.
Как ega23 я оказалась невнимательна, и также, как ega23 своевременно заметила свою ошибку.
Благодаря Вашему StartTime. Спасибо.
Действительно, нужна еще одна переменная, которая

предназначена для хранения старта и только старта.
Тот пинг-понг, что я наворотила, работал на первом шаге, т.е. g_tmpTime := Time (ваше Now) - g_tmpTime (изначально хранящий StartTime).
А чтобы дальше подумать, на это меня не хватило :)
В остальном есть некоторые минусы для меня:
Во-первых, TimeToStr отображает часы:минуты:секунды, а мне надо
минуты:секунды:миллисекунды (из-за чего частоту таймера придется выставить = 10 вместо 1000).
Во-вторых, Now содержит и дату и время, а мне необходимо только время (т.е. Time). Экономия какая-никакая.
В-третьих, ...
А впрочем, Ваша конструкция - действительно секундомер, в буквальном смысле слова, как и был изначально поставлен вопрос.
Мой респект.

Итоговый код:
//на старте
 g_TimeStart := Time;
 Timer1.Enabled := TRUE;
//в теле таймера
 Label3.Caption := FormatDateTime("nn:ss:zz", Time - g_TimeStart);


Кстати, на этом примере отлично видно, то, что раньше уже обсуждалось: секунды в таймере - ненастоящие.
Каждую "секунду" (1000) таймер отображает и миллисекунды, которые почти все время разные (!). Т.е. интервалы
видно, что неровные.


 
Idiliya ©   (2004-05-25 23:14) [25]


> ega23 ©   (25.05.04 10:01) [22]

Отдельное мерси ega23 ©
GetTickCount почти оседлала - прочла, что это такое и с чем его едят.
Он содержит в себе чистые миллисекунды.
Причем от старта системы.
Чем же он лучше Time?


 
Anatoly Podgoretsky ©   (2004-05-25 23:23) [26]

Idiliya ©   (25.05.04 23:13) [24]
Я по пунктикам

1. После того как из Mow будет отнята стартовая дата, то никакой даты не будет, а будет прошедшее время в формате
TDateTime, после преобразованя секунды минуты и так дале

2. Если нужны миллисекунды в отражение то надо вместо TimeToStr использовать FormatDateTime

3. Функцию Time использовать нельзя, поскольку будет ошибка при переходе через полночь

4. С GetTickCount придется делать допольнительные телодвижения, или преобразовывать в TDateTime или вручную форматировать вывод.

Резюме Самое подходящее для секундомера это Now и одну из функций форматирования


 
Anatoly Podgoretsky ©   (2004-05-25 23:24) [27]

При желании каждый отдельный пунктик можно отдельно пообсуждать если есть что то непонятное


 
Idiliya ©   (2004-05-25 23:29) [28]


> Anatoly Podgoretsky ©   (25.05.04 23:24) [27]

Вопросов нет. Спасибо, все понятно.
Принимаю Now, как догму.


 
Fay ©   (2004-05-26 01:29) [29]


> Резюме Самое подходящее для секундомера это Now и одну из
> функций форматирования

Можно и так
var
 st : TSystemTime;
begin
 GetSystemTime(st);
 ShowMessage(Format("%2.2d:%2.2d:%3.3d", [st.wMinute, st.wSecond, st.wMilliseconds]))



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

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

Наверх




Память: 0.55 MB
Время: 0.054 c
1-1085416549
Lena19
2004-05-24 20:35
2004.06.06
задержка выполнения без нагрузки на проц


6-1081866891
Denis555
2004-04-13 18:34
2004.06.06
Как получить html содержимое страницы


3-1084863521
Dark Man
2004-05-18 10:58
2004.06.06
А генераторы ихде???


1-1085145192
yustaz
2004-05-21 17:13
2004.06.06
Проблемы с функцией Pos()


1-1085408550
$Hic0
2004-05-24 18:22
2004.06.06
Events