Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.06.06;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.034 c
1-1085033926
Teetotaller
2004-05-20 10:18
2004.06.06
Избавление от белых полей вокруг текста


14-1084785001
olookin
2004-05-17 13:10
2004.06.06
Предусматривает ли КЗОТ?


4-1082374540
Сережа550
2004-04-19 15:35
2004.06.06
WM_LBUTTONDOWN и WM_LBUTTONUP


1-1085072138
Nikoss
2004-05-20 20:55
2004.06.06
Как узнать порядковый номер объекта в динам. массиве ...


1-1085409699
Bent
2004-05-24 18:41
2004.06.06
Класс в Thread





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