Часто при программировании в некоторых местах программы необходимо замерять время исполнения кода, в других просто останавливать выполнение не некоторое время. Например, если писать игру, необходимо создавать код, который бы ограничивал скорость игры. Конечно, если игра очень тяжелоя, то некоторое время она может существовать без такого ограничителя.
Но со временем вычислительная мощь компютеров растет (к сожелению не сама по себе) и в игры без ограничителя скорости играть становится невозможно. Или вы решили написать бенчмарк для процессора. Тут уже нужны очень точные средства для замера времени исполнения кода. Таких примеров можно привести уйму.
Проще сказать, что в любой более — мение серезной программе измерение времени просто необходимо. К сожалению штатные средства в Паскале ограничиваются только процедурой Delay что описана в модуле CRT. Но она очень сильно зависит от производительности системы. Конечно, можно использовать процедуру GetTime, но она довольно громоздка. А стандартных процедур по замеру времени выполнения кода вобще нет.
Время выполнения программы на с++
Ну и не надо! Мы ведь не чайники? Конечно, не чайники! Сами напишем. При написании программ последовательный код стараются обединить в цыклы. Код, повторяющийся в програме выносят в отдельные процедуры и функции. А код, который явно будет использоватся не в одной программе, выносят в модули. Мы так и сделаем.
Давайте создадим в Паскале файл TIMER.PAS и начнем. Как известно название модуля и файла должны совпадать, поетому пишем:
Далее необходимо создать интерфейсную часть модуля. Тут давайте остановимся и разберемся что нам нужно. Во-первых нам нужны средства для измерения времени исполнения кода. Во-вторых средства по остановке программы на определенное время. Кроме того, при остановке может, понадобится вывод времени, которое прошло.
interface
procedure Start (var T:longint);
procedure Stop (var T:longint);
procedure Pause (T:longint; Show:boolean);
Итак, мы обявили три процедуры. Процедуры Start и Stop будут служить для измерения времени выполнения кода, а Pause станет заменой Delay. Переменная T — будит служить для передачи данных о времени. Show — для разрешения или запрещения вывода времени на екран. Далее следует исполнительная часть.
Она служит для обявления локальных констант, переменных и типов. В данном модуле они нам не нужны:
Далее следует самое интересное. Вы еще не задумывались каким же способом мы будем производить замер времени? А почему бы не использавать аппаратный таймер? Темболее это очень просто:
SystemTimer:longint absolute $0040:$006C;
Вот и все! Нет, модуль не весь, но мы имеем полный доступ к аапаратному таймеру, расположеному по физическому адресу $0040:$006C. Значение двойного слова по этому адресу увеличивается на единицу 18.2 раза в секунду и независит от производительности системы. Нам осталось только написать примитивные процедуры для оперирования с таймером:
procedure Start (var T:longint);
Программа на Паскале Угадай число. Переменные, случайные числа, условные переходы
begin
T:=SystemTimer;
end;
procedure Stop (var T:longint);
begin
T:=SystemTimer-T;
end;
procedure Pause (T:longint; Show:boolean);
var Xn,Xt:longint;
begin
Xt:=0;
Xn:=SystemTimer;
While ((Xt-Xn)/18.2)*1000 < T do
begin
Xt:=SystemTimer;
If Show then
writeln((xt-xn)/18.2:6:4)
end;
end;
Ну, и долгожданный
Все, компилируем. Хочется сразу проверить работу, не так ли?
Program TimerPrimer;
uses timer;
Var i : integer;
a :Real;
Time : LongInt;
begin
Randomize;
Start(Time);
For i:=1 to 30000 do
a:=Sin(sqrt(i))*Cos(sqrt(Random(10000)));
Stop(Time);
Writeln(‘Время выполнения: ‘,Time/18.2:6:4);
Readln;
Pause(10000, True);
end.
Данная программа демонстрирует возможности модутя Timer. В начале она исполняет цыкл от 1 до 30000 в котором высчитывает значение а. Время выполнения этого цыкла и замеряют наши процедуры Start и Stop. После чего, дождавшись нажатия на Enter делаем паузу на 10.000 секунд с разрешаем процедуре Pause осуществлять вывод на екран.
Теперь вы сможете использовать точный таймер в своих программах. А почему же я не воспользовался процедурой GetTime? Только из-за ее громоздкости? Конечно нет. Посмотрите на код. Что мы собственно использовали? Только прямой доступ к физическому адресу аппаратного таймера. Так кто мешает использовать его в других языках программирования?
Вот тут то и оно.
Источник: www.cyberguru.ru
Измерение времени в PASCAL
Для точного измерения времени под Windows в Free PASCAL используется функция QueryPerformanceCounter. Ниже показан пример использования данной функции:
start, finish, res: int64;
writeln(‘Затрачено ‘, (finish — start) / res, ‘ секунд’ );
В PASCAL ABC.NET необходимо использовать встроенный класс Stopwatch. Пример кода приведен ниже (код взят из примеров интегрированной среды разработки PABCWork.NETSamplesNETLibrariesOther).
// Sto9pwatch — класс высокоточного таймера (с точностью до 0.001 с)
var stopWatch := new System.Diagnostics.Stopwatch;
writelnFormat(‘Время работы: ::.’,ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
Источник: sites.google.com
Как сделать программу-секундомер на Паскале
Итак, для начала откроем программу. Создадим новый файл и укажем подключаемые модули. В данном случае нам нужен модуль для работы с консолью — CRT.
для этого напишем:
Укажем переменные i, s, m — переменные вещественного типа.
Для начала программы напишем:
И укажем заголовок консольного окна:
Процедура TextColor назначает цвет текста, а оператор Write выводит текст на экран:
TextColor(LightGreen);
WriteLn(‘Нажмите Enter чтобы запустить секундомер’);
WriteLn(‘Нажмите повторно, чтобы остановить’);
Write(‘Нажмите ещё раз, чтобы запустить заново’);
Окончание Ln осуществляет переход на следующую строку.
Оператор ReadLn вводит значения с клавиатуры, но в даном случае он просто ждёт, когда пользователь нажмёт Enter:
Делаем бесконечный цикл:
while (true) do
begin
Конструкция while (true) do begin переводится как: Пока (условие) делай(). Спрашивается зачем здесь begin?
В данном случае нам нужен составной оператор, а это значит что пока условие истинно выполняется несколько операторов. Если бы здесь не стоял begin то после While выполнялся только один оператор, что привело бы неправильной работе программы. Чтобы закончить оператор While в конце мы напишем end.
Теперь обнулим счётчик:
Следующий оператор переводится как: пока не нажата клавиша делай().
while not keypressed do
begin
Оператор ClrScr очищает экран:
Ставим условим: если секунд больше 60 и меньше 3600(это нужно для того, чтобы когда времени было больше часа, программа печатала только то что находится после третьего if) то:
Переменная m(минуты) равна: секунды поделённые на 60 и округлённые до челой части.
А переменная s(секунды без минут) равна: все секунды минус минуты умноженные на 60.
Оператор Write пишет сколько прошло минут и секунд, а оператор end заканчивает работу begin стоящего после условия if:
Write(m, ‘минут(а/ов) и ‘, s:1:2, ‘секунд(а/ы)’)
end;
Функция :1:2 означает что секунды нужно писать с двумя знаками после знаками после запятой.
Если секунд меньше 60 то просто пиши сколько секунд прошло с двумя знаками после запятой:
Если секунд больше 3600(то есть больше часа) то:
if i > 3600 then begin
m := Int(i / 60);
s := i — m * 60;
ch := Int(m / 60);
m := m — ch * 60;
Write(ch, ‘ час(а/ов) ‘, m, ‘ минут(а/ы) и ‘, s:1:2, ‘ секунд(а/ы)’);
end;
Итак, программа написала что прошло 0 секунд, теперь увеличивает счётчик i на 10 миллисекунд и так как программа выполняет всё мгновенно делаем задержку на это же время:
i := i + 0.01;
Delay(10);
Далее делаем конец для оператора While (not keypressed):
end;
Если пользователь нажал клавишу Enter, то программа ждёт когда когда он опять её нажмёт, чтобы запустить секундомер заново:
Неслучайно мы поставили обнуление счётчика после оператора While (true), потому что когда пользователь второй раз нажмёт Enter, программа пойдёт как раз с него, обнулит счётчик и начнёт отсчет заново.
Далее делаем конец для While и для всей программы:
Вот вся программа полностью:
var
i: Real;
s: Real;
m: Real;
ch: Real;
begin
SetWindowTitle(‘Секундомер’);
TextColor(LightGreen);
WriteLn(‘Нажмите Enter чтобы запустить секундомер’);
WriteLn(‘Нажмите повторно, чтобы остановить’);
Write(‘Нажмите ещё раз, чтобы запустить заново’);
ReadLn;
while (true) do
begin
i := 0;
while not keypressed do
begin
ClrScr;
if (i > 60) and (i <3600) then begin
m := Int(i / 60);
s := i — m * 60;
Write(m, ‘минут(а/ов) и ‘, s:1:2, ‘секунд(а/ы)’)
end;
if i < 60 then
Write(‘ ‘, i:1:2, ‘ секунд(а/ы)’);
if i > 3600 then begin
m := Int(i / 60);
s := i — m * 60;
ch := Int(m / 60);
m := m — ch * 60;
Write(ch, ‘ час(а/ов) ‘, m, ‘ минут(а/ы) и ‘, s:1:2, ‘ секунд(а/ы)’);
end;
i := i + 0.01;
Delay(10);
end;
Readln;
Readln;
end;
end.
Получилось не очень красиво, но программа работает правильно!
Источник: www.kakprosto.ru