Паскаль как найти время

Для точного измерения времени под Windows в Free PASCAL используется функция QueryPerformanceCounter. Ниже показан пример использования данной функции:

program Time;

uses

Windows;

var

start, finish, res: int64;

begin

QueryPerformanceFrequency(res); {Вызывается один раз в начале программы}

QueryPerformanceCounter(start);

{Участок кода, для которого будет замеряться время выполнения}

QueryPerformanceCounter(finish);

writeln(‘Затрачено ‘, (finish — start) / res, ‘ секунд’ );

end.

В PASCAL ABC.NET необходимо использовать встроенный класс Stopwatch. Пример кода приведен ниже (код взят из примеров интегрированной среды разработки PABCWork.NETSamplesNETLibrariesOther).

program Time;

var

ts : System.TimeSpan;

// Sto9pwatch — класс высокоточного таймера (с точностью до 0.001 с)

begin

var stopWatch := new System.Diagnostics.Stopwatch;

stopWatch.Start;

{Участок кода, для которого будет замеряться время выполнения}

stopWatch.Stop;

ts := stopWatch.Elapsed;

writelnFormat(‘Время работы: {0:00}:{1:00}:{2:00}.{3:000}’,ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);

end.


Most of the softwares you write need implementing some form of date functions returning current date and time. Dates are so much part of everyday life that it becomes easy to work with them without thinking. Pascal also provides powerful tools for date arithmetic that makes manipulating dates easy. However, the actual name and workings of these functions are different for different compilers.

Getting the Current Date & Time

Pascal’s TimeToString function gives you the current time in a colon(: ) delimited form. The following example shows how to get the current time −

program TimeDemo;
uses sysutils;

begin
   writeln ('Current time : ',TimeToStr(Time));
end.

When the above code was compiled and executed, it produces the following result −

Current time : 18:33:08

The Date function returns the current date in TDateTime format. The TDateTime is a double value, which needs some decoding and formatting. The following program demonstrates how to use it in your program to display the current date −

Program DateDemo;
uses sysutils;
var
   YY,MM,DD : Word;

begin
   writeln ('Date : ',Date);
   DeCodeDate (Date,YY,MM,DD);
   writeln (format ('Today is (DD/MM/YY): %d/%d/%d ',[dd,mm,yy]));
end.

When the above code was compiled and executed, it produces the following result −

Date: 4.111300000000000E+004
Today is (DD/MM/YY):23/7/2012

The Now function returns the current date and time −

Program DatenTimeDemo;
uses sysutils;
begin
   writeln ('Date and Time at the time of writing : ',DateTimeToStr(Now));
end.

When the above code was compiled and executed, it produces the following result −

Date and Time at the time of writing : 23/7/2012 18:51:

Free Pascal provides a simple time stamp structure named TTimeStamp, which has the following format −

type TTimeStamp = record
   Time: Integer;
   Date: Integer;
end;

Various Date & Time Functions

Free Pascal provides the following date and time functions −

Sr.No. Function Name & Description
1

function DateTimeToFileDate(DateTime: TDateTime):LongInt;

Converts DateTime type to file date.

2

function DateTimeToStr( DateTime: TDateTime):;

Constructs string representation of DateTime

3

function DateTimeToStr(DateTime: TDateTime; const FormatSettings: TFormatSettings):;

Constructs string representation of DateTime

4

procedure DateTimeToString(out Result: ;const FormatStr: ;const DateTime: TDateTime);

Constructs string representation of DateTime

5

procedure DateTimeToString(out Result: ; const FormatStr: ; const DateTime: TDateTime; const FormatSettings: TFormatSettings);

Constructs string representation of DateTime

6

procedure DateTimeToSystemTime(DateTime: TDateTime; out SystemTime: TSystemTime);

Converts DateTime to system time

7

function DateTimeToTimeStamp( DateTime: TDateTime):TTimeStamp;Converts DateTime to timestamp

8

function DateToStr(Date: TDateTime):;

Constructs string representation of date

9

function DateToStr(Date: TDateTime; const FormatSettings: TFormatSettings):;

Constructs string representation of date

10

function Date: TDateTime;

Gets current date

11

function DayOfWeek(DateTime: TDateTime):Integer;

Gets day of week

12

procedure DecodeDate(Date: TDateTime; out Year: Word; out Month: Word; out Day: Word);

Decodes DateTime to year month and day

13

procedure DecodeTime(Time: TDateTime; out Hour: Word; out Minute: Word; out Second: Word; out MilliSecond: Word);

Decodes DateTime to hours, minutes and seconds

14

function EncodeDate(Year: Word; Month: Word; Day: Word):TDateTime;

Encodes year, day and month to DateTime

15

function EncodeTime(Hour: Word; Minute: Word; Second: Word; MilliSecond: Word):TDateTime;

Encodes hours, minutes and seconds to DateTime

16

function FormatDateTime(const FormatStr: ; DateTime: TDateTime):;

Returns string representation of DateTime

17

function FormatDateTime(const FormatStr: ; DateTime: TDateTime; const FormatSettings: TFormatSettings):;

Returns string representation of DateTime

18

function IncMonth(const DateTime: TDateTime; NumberOfMonths: Integer = 1):TDateTime;

Adds 1 to month

19

function IsLeapYear(Year: Word):Boolean;

Determines if year is leap year

20

function MSecsToTimeStamp(MSecs: Comp):TTimeStamp;

Converts number of milliseconds to timestamp

21

function Now: TDateTime;

Gets current date and time

22

function StrToDateTime(const S:):TDateTime;

Converts string to DateTime

23

function StrToDateTime(const s: ShortString; const FormatSettings: TFormatSettings):TDateTime;

Converts string to DateTime

24

function StrToDateTime(const s: AnsiString; const FormatSettings: TFormatSettings):TDateTime;

Converts string to DateTime

25

function StrToDate(const S: ShortString):TDateTime;

Converts string to date

26

function StrToDate(const S: Ansistring):TDateTime;

Converts string to date

27

function StrToDate(const S: ShortString; separator: Char):TDateTime;

Converts string to date

28

function StrToDate(const S: AnsiString; separator: Char):TDateTime;

Converts string to date

29

function StrToDate(const S: ShortString; const useformat: ; separator: Char):TDateTime;

Converts string to date

30

function StrToDate(const S: AnsiString; const useformat: ; separator: Char):TDateTime;

Converts string to date

31

function StrToDate(const S: PChar; Len: Integer; const useformat: ; separator: Char = #0):TDateTime;

Converts string to date

32

function StrToTime(const S: Shortstring):TDateTime;

Converts string to time

33

function StrToTime(const S: Ansistring):TDateTime;

Converts string to time

34

function StrToTime(const S: ShortString; separator: Char):TDateTime;

Converts string to time

35

function StrToTime(const S: AnsiString; separator: Char):TDateTime;

Converts string to time

36

function StrToTime(const S: ; FormatSettings: TFormatSettings):TDateTime;

Converts string to time

37

function StrToTime(const S: PChar; Len: Integer; separator: Char = #0):TDateTime;

Converts string to time

38

function SystemTimeToDateTime(const SystemTime: TSystemTime):TDateTime;

Converts system time to datetime

39

function TimeStampToDateTime(const TimeStamp: TTimeStamp):TDateTime;

Converts time stamp to DateTime

40

function TimeStampToMSecs(const TimeStamp: TTimeStamp):comp;

Converts Timestamp to number of milliseconds

41

function TimeToStr(Time: TDateTime):;

Returns string representation of Time

42

function TimeToStr(Time: TDateTime; const FormatSettings: TFormatSettings):;

Returns string representation of Time

43

function Time: TDateTime;

Get current time

The following example illustrates the use of some of the above functions −

Program DatenTimeDemo;
uses sysutils;
var
year, month, day, hr, min, sec, ms: Word;

begin
   writeln ('Date and Time at the time of writing : ',DateTimeToStr(Now));
   writeln('Today is ',LongDayNames[DayOfWeek(Date)]);
   writeln;
   writeln('Details of Date: ');
   
   DecodeDate(Date,year,month,day);
   writeln (Format ('Day: %d',[day]));
   writeln (Format ('Month: %d',[month]));
   writeln (Format ('Year: %d',[year]));
   writeln;
   writeln('Details of Time: ');
   
   DecodeTime(Time,hr, min, sec, ms);
   writeln (format('Hour: %d:',[hr]));
   writeln (format('Minutes: %d:',[min]));
   writeln (format('Seconds: %d:',[sec]));
   writeln (format('Milliseconds: %d:',[hr]));
end.

When the above code was compiled and executed, it produced the following result:

Date and Time at the time of writing : 7/24/2012 8:26:
Today is Tuesday
Details of Date:
Day:24
Month:7
Year: 2012
Details of Time:
Hour: 8
Minutes: 26
Seconds: 21
Milliseconds: 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
rogram Tower_of_hanoi;
 
uses CRT;
 
procedure Hanoi (n : integer; x, y, z : char);
begin
     if n <> 0 then
     begin
          Hanoi (n - 1, x, z, y);
          writeLn ('Перемещаем диск ', n, ' c  ',  x,  ' на ', y);
          Hanoi (n - 1, z, y, x)
     end
end;
 
var
   disk : integer;
begin
     ClrScr;
     write ('Сколько дисков ?');
     readLn (disk);
       GetTime(hour,min,sec,hund);//определяем время начала программы
writeln(hour,':',min,':',sec,':',hund);
t1:=sec*100+min*6000+hund;
     Hanoi (disk, 'X', 'Y', 'Z')
 
GetTime(hour,min,sec,hund);//время окончания
writeln(hour,':',min,':',sec,':',hund);
t2:=sec*100+min*6000+hund;;
t:=t2-t1;//прошло времени
end.

>
Как замерять время выполнения кода?
, Например сколько времени выполняется алгоритм

  • Подписаться на тему
  • Сообщить другу
  • Скачать/распечатать тему



Сообщ.
#1

,
09.12.03, 15:26

    Самым простым способом является одновременно самый очевидный:
    Узнаём и запоминаем время, потом делаем нужное нам действие, и сразу после него опять узнаём и запоминаем время.
    Разница между временем до действия и временем после действия и будет временем выполнения действия.

    В паскале есть стандартная процедура модуля Dos — GetTime.
    Она узнаёт, сколько времени в момент её выполнения.
    Вот её синтаксис:
    procedure GetTime(var Hour, Minute, Second, Second100:word);

    Её параметрамы должны быть обязательно переменные. После её выполнения в этих переменных будет содержаться время того момента, когда выполнится эта процедура:

    • Hour — Час (значение от 0 до 23)
    • Minute — Минута (значение от 0 до 59)
    • Second — Секунда (значение от 0 до 59)
    • Second100 — Сотая часть секунды (значение от 0 до 99)

    Используя эту процедуру мы можем занести в переменные время до выполнения нужного нам действия, и в другие переменные время после выполнения нужного нам действия.
    После этого можно посчитать разницу во времени, и эта разница будет длительностью выполнения замеряемого действия.

    Чтобы посчитать разницу нужно перевести время до выполнения и время после выполнения к количеству сотых частей секунды. Нельзя напрямую сравнивать к примеру просто секунды. Почему?
    Предположим в момент замера времени до выполнения нужного нам действия было время 10 минут 58 секунд. А в момент замера времени после выполнения было 11 минут 15 секунд. Если мы вычтем из секунд-после секунды-до, мы получим (15-58)=-43 секунды. Но ведь это неверно %)
    Так получилось из-за того, что за время, пока выполнялась программа началась новая минута. Если же преобразовать всё время к количеству сотых частей секунды, то такой проблемы не возникнет.
    Вот пример действующего кода:

    ExpandedWrap disabled

      uses dos;

      var

        h1,m1,s1,t1:word;

        h2,m2,s2,t2:word;

        d:longint;

      begin

        gettime(h1,m1,s1,t1);

        … {любое действие, продолжительность которого измеряем}

        gettime(h2,m2,s2,t2);

        {вычислим время выполнения d — результат будет в сотых долях секунды}

        d:=(longint(h2)*360000+longint(m2)*6000+s2*100+t2)- {количество сотых долей секунды после выполнения}

           (longint(h1)*360000+longint(m1)*6000+s1*100+t1); {их количество до выполнения действия}

        writeln(‘Действие выполнялось ‘,d/100:0:2,’ секунды’);

      end.

    П.С. Следует добавить, что хотя этот способ и является самым простым, он отнюдь не самый точный, поскольку во время замера входит так же время выполнения процедуры GetTime, и кроме того это время может зависеть от состояния Директив компилятора.

    P.P.S:
    Можно пойти чуть дальше, и написать функцию fGetTime:

    ExpandedWrap disabled

      function fGetTime: LongInt;

      var hr, min, sec, sec_100: word;

      begin

        GetTime(hr, min, sec, sec_100);

        fGetTime := longint(hr)*360000 + longint(min)*6000 + sec*100 + sec_100;

      end;

      { и работать с ней: }

      var before, after: longint;

      begin

        before := fGetTime;

        …

        after := fGetTime;

        writeln(‘Действие выполнялось ‘, (after — before) / 100:0:2,’ секунды’)

      end;

    V877

    Сообщение отредактировано: volvo877 — 01.09.08, 07:35


    Visitor



    Сообщ.
    #2

    ,
    11.12.03, 19:11

      Совсем забыл, что хотел запостить :(

      Для процессоров выше i486 существует способ очень точно сравнить время выполнения двух участков кода — ето встроенный в процессор счетчик тактов. Ниже приведены два исходника — процедура, считывающая значение етого счетчика, и пример ее использования на BP7.
      tsc.asm

      ExpandedWrap disabled

                .MODEL LARGE

                .CODE

                .386c

        PUBLIC  READTSC

        READTSC PROC FAR

                enter 0, 0

                push ds

                db   0fh, 31h; RDTSC opcode

                mov  bx, ss:[bp+8]

                mov  ds, bx

                mov  bx, ss:[bp+6]

                mov  [bx], eax

                mov  [bx+4], edx

                pop ds

                leave

                retf 4

        READTSC ENDP

                END

      sample.pas

      ExpandedWrap disabled

        {$N+}

        procedure ReadTSC(Var counter : Comp); far; external;

        {$L tsc.obj}

        Var a1, a2, a3 : Comp;

        begin

            ReadTSC(a1);

            Writeln(‘Working :)’);

            ReadTSC(a2);

            Writeln(a1:20:0, ‘, ‘, a2:20:0, ‘, ‘, (a2-a1):20:0)

        end.

      В прикрепленном файле то же самое, tsc.asm оттранслирован.

      P.S. Обратите внимание и сделайте выводы, как много времени занимает вывод на екран. :)

      Прикреплённый файлПрикреплённый файлtsc.zip (0.93 Кбайт, скачиваний: 583)


      Vesper



      Сообщ.
      #3

      ,
      12.12.03, 10:44

        Если не хочется подключать модуль DOS, замерить время можно с помощью взятия значения напрямую из памяти по адресу $0046C (4 байта). Там хранится число «тиков» встроенных часов реального времени, которые тикают 18.54 раз в секунду. И именно оттуда тащат его функции модуля.
        Если у вас все еще нет процессора Pentium (или есть, но нужно измерять время на процессоре ниже него), можно разогнать встроенный таймер, при этом нужно будет использовать встроенный ассемблер. Вот этот код по-моему достаточно откомментирован:

        ExpandedWrap disabled

          procedure bogusprocedure;near; assembler;

          asm

          end;

          var int08save:pointer;

              int08handler_count:longint;

              int08handler_lessercount:word;

              int08handler_tickin:boolean;

          procedure int08handler;assembler;{no sense of far, it’s int handler, so must have iret inside}

          asm

            sti

            push ax

            push dx

            push ds

            mov ax,seg @data

            mov ds,ax {loading DS, probably it’s changed}

            mov al,int08handler_tickin

            or al,al

            je @hnd_l1 {if not tickin jump forward}

            db 66h

            inc word ptr int08handler_count

          @hnd_l1:

            dec int08handler_lessercount

            jne @hnd_l3

            mov int08handler_lessercount,0100h {256, must be 65536 div (speedup level)}

            {ok, let’s call normal handler after all that}

            pushf

            call dword ptr int08save

            jmp @hnd_l2

          @hnd_l3:

            mov al,20h

            out 20h,al   {funny, BIOS caller uses call blablabla and ret instead of jmp short}

            db 0ebh,0

            call bogusprocedure

          @hnd_l2:

            pop ds

            pop dx

            pop ax

            iret

          end;

        Обработчик прерывания устанавливается на прерывание 08, перед этим нужно сохранить старый вектор вызовом getintvec($08,addr(int08save)), иначе процедура не будет работать :(
        Таймер программируется вот так:

        ExpandedWrap disabled

          {programming timer channel 0, tickin 256, mode 3, hex counter, greater byte only}

          asm

              cli

              mov al,00100110b

              out 43h,al

              call bogusprocedure

              mov al,1

              out 40h,al

              call bogusprocedure

              sti

          end;

        Вызов bogusprocedure стоит из-за того, что порт может не успеть принять записанный байт до того, как в него запишут следующий.
        Значение AL в первом OUT флаговое, это байт управления таймером. Биты 7 и 6 содержат номер канала (для часов это 0), 5й и 4й управляют записью соответственно старшего и младшего байта счетчика таймера, 3,2,1 биты содержат режим работы (новый) счетчика, для часов используется режим 3 — периодические прямоугольные колебания выходного сигнала, каждый полупериод длится N/2 колебаний генератора (1193182 Гц), прерывание генерируется каждый переход с низкого на высокий уровень. 0й байт определяет формат записываемого счетчика (1 — двоично-десятичный, 0 — шестнадцатеричный). При записи обоих байтов счетчика сначала записывается младший байт. Для возврата в нормальное состояние в счетчик должен быть записан 0 в оба байта, что соответствует значению счетчика 65536 и нормальной частоте прерываний. Т.е. код для возврата:

        ExpandedWrap disabled

          asm

              cli

              mov al,00110110b

              out 43h,al

              call bogusprocedure

              mov al,0

              out 40h,al

              call bogusprocedure {ok, delay also goes here}

              out 40h,al

              call bogusprocedure

              sti

          end;

        Естественно, нужно еще и вернуть старый вектор, setintvec($08,addr(int08save));
        Работой счетчика (на случай выключения из анализа процедуры или двух ;) ) можно управлять переменной int08handler_tickin, если она true, то счет идет. Вне зависимости от нее, старый вектор прерывания вызывается с нужной частотой.


        Vesper



        Сообщ.
        #4

        ,
        30.12.03, 13:55

          Не стал править предыдущий пост, он не расконвертился :(
          Насчет таймера в памяти ДОС:
          При каждом срабатывании прерывания 08 происходит увеличение значения meml[0:$046C] на единицу, далее оно проверяется на достижение значения $1800B0 (в десятичной системе 1573040), которое соответствует переходу через полночь (24 часа). Если на часах полночь, ставится в единицу байт по адресу (вроде бы mem[0:$0467], точно не помню). Это значение меняется 18.2 раза в секунду (Some1 был прав) и доступно через «массив» meml любой программе, работающей под ДОС. Чтобы измерить время, нужно:
          1) Определить кусок программы, для которого вам нужно узнать время его работы;
          2) Сохранить значение этого участка памяти: starttime:=meml[0:$046C]; вставив этот оператор сразу перед началом куска;
          3) Сразу после него считать значение еще раз: endtime:=meml[0:$046C]; Для иллюстрации я написал 2 переменные, можно обойтись и одной :)
          4) Проверить, не было ли пОлночи в процессе работы: if endtime<starttime then inc(endtime,$1800B0);
          5) Осталось взять разницу между значениями и разделить её на 18.2. Результат — время в секундах с точностью плюс-минус 0.05с.
          Например, для тестовых задач оно определяется вот так:

          ExpandedWrap disabled

            time:=meml[0:$046C];

            proces;

            time:=meml[0:$046C]-time;

            if time<0 then time:=time+$1800B0;

            writeln(time/18.2:6:2);

          Использован кусок кода Кришкина, немного подправленный. proces — процедура, решающая задачу.

          PS. Если в запрошенном куске будет запрос данных от пользователя, чистого времени вы уже не получите. Если, конечно, вам не нужно время реакции (или скорость набора) пользователя. :D Например, вам нужно узнать, сколько времени ваш ребенок (если есть, иначе ученик ;) ) решал задачку в уме. Делаем так:

          ExpandedWrap disabled

            write(‘Задача №3: траляляляляляля. Введите ответ:’);

            time:=meml[0:$046C];

            readln(x);

            time:=meml[0:$046C]-time;

            if time<0 then time:=time+$1800B0;

            writeln(‘Долговато пожалуй, целых ‘,time/18.2:6:2,’ секунд’);

            if x<>n then writeln(‘Кстати, ответ неверен.’) else writeln(‘Правильно.’);

          Хотя вряд ли вы будете ребенка пытать арифметикой в полночь. :D :D

          Guru

          Romtek



          Сообщ.
          #5

          ,
          13.02.04, 22:49

            Moderator

            *******

            Рейтинг (т): 188

            ExpandedWrap disabled

              { Это только интерфейсная часть кода. Целый код модуля находится в архиве }

              Unit XTIMER;

              INTERFACE

              Var elapsed: Longint; { прошедшее время, в милисекундах. }

              Procedure ClockOn;    { включает счётчик времени }

              Procedure ClockOff;   { выключает его }

              Procedure PrintTime;  { выводит прошедшее время }

              IMPLEMENTATION

              END.

            тестировалось также на Пентиумах II и III, без использования модуля CRT.
            Исходник модуля в архиве.

            Сообщение отредактировано: Romtek — 02.12.04, 12:22


            Прикреплённый файлПрикреплённый файлxtimer.zip (1.32 Кбайт, скачиваний: 529)


            Александр.



            Сообщ.
            #6

            ,
            05.04.04, 13:38

              Junior

              *

              Рейтинг (т): 0

              А на TMT можно использовать модуль ZenTimer.

              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

              0 пользователей:

              • Предыдущая тема
              • Pascal: Общие вопросы
              • Следующая тема

              [ Script execution time: 0,0376 ]   [ 16 queries used ]   [ Generated: 27.05.23, 23:01 GMT ]  

              уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

              Несколько лет назад я описывал четыре способа измерения точного времени выполнения операции в Delphi. Сегодня рассмотрим этот же вопрос, но уже применительно к Lazarus и Free Pascal. Учитывая, что Lazarus можно использовать как в Windows, так и в Linux, способы того, как измерить точное время выполнения операции в Lazarus и Delphi будут немного различаться. Для начала, определимся с тем, время выполнения какой операции мы будем измерять. Путь это будет вот такая простенькая процедура:

              procedure DoSomething;
              var i,k: QWord;
              begin
                k:=0;
                for i:=0 to 999999999 do
                  inc(k);
              end;

              Учитывая то, что на данный момент я могу проверить работоспособность того или иного способа только на двух платформах: Windows и Linux, ниже я буду давать описание применимости различных способов точного измерения времени, исходя из проверок именно на этих платформах.

              Способ №1 — использование функции Now()

              Платформы: Windows, Linux.

              Как и в случае с Delphi этот способ вполне подойдет для измерения времени, например, следующим образом:

              procedure TForm1.Button2Click(Sender: TObject);
              var start, stop: TDateTime;
              begin
                start:=Now;//засекаем начальное время
                DoSomething;
                stop:=Now;//засекаем конечное время
                {выводим время выполнения операции с точностью до секунды}
                Memo1.Lines.Add(SecondsBetween(start, stop).ToString);
              end;

              И, хотя в справке Free Pascal ничего не сказано про точность функции Now() (в справке Delphi написано, что точность составляет порядка секунды), я не стал рисковать и все также использовал функцию SecondsBetween() из модуля DateUtils для расчёта количества секунд, пошедших на выполнение операции.

              Способ №2 — использование функции GetTickCount

              Платформы: Windows, Linux

              В настоящее время, в модуле sysutils Free Pascal содержатся две функции, одна из которых помечена как deprecated:

              function GetTickCount: LongWord; deprecated 'Use GetTickCount64 instead';
              function GetTickCount64: QWord;

              Как и в случае с Delphi, используя GetTickCount можно получить время в миллисекундах, затраченное на выполнение операции. Однако, в справке Free Pascal про эту функцию сказано следующее: функция полезна для измерения времени, но не следует делать никаких предположений относительно интервала между тиками. В принципе, примерно тоже сказано и в справке Windows относительно их функций GetTickCount.

              Использование функций:

              procedure TForm1.Button1Click(Sender: TObject);
              var Start, Stop: QWord;
              begin
                Start:=GetTickCount64;
                DoSomething;
                Stop:=GetTickCount64;
                Memo1.Lines.Add((stop-start).ToString);
              end;

              Стоит отметить, что в зависимости от платформы на которой собирается приложение, GetTickCount64 имеет различные реализации. Так, например, если мы собираем приложение под Windows, то GetTickCount64 будет использовать одноименную функцию из модуля Windows:

              function GetTickCount64: QWord;
              {$IFNDEF WINCE}
              var
                lib: THandle;
              {$ENDIF}
              begin
              {$IFNDEF WINCE}
                { on Vista and newer there is a GetTickCount64 implementation }
                if Win32MajorVersion &gt;= 6 then begin
                  if not Assigned(WinGetTickCount64) then begin
                    lib := LoadLibrary('kernel32.dll');
                    WinGetTickCount64 := TGetTickCount64(
                                           GetProcAddress(lib, 'GetTickCount64'));
                  end;
                  Result := WinGetTickCount64();
                end else
              {$ENDIF}
                  Result := Windows.GetTickCount;
              end;

              Если же мы используем Linux, то реализация GetTickCount64 основывается на использовании clock_gettime() — функции из языка Си:

              function GetTickCount64: QWord;
              var
                tp: TTimeVal;
                {$IFDEF HAVECLOCKGETTIME}
                ts: TTimeSpec;
                {$ENDIF}
               
              begin
               {$IFDEF HAVECLOCKGETTIME}
                 if clock_gettime(CLOCK_MONOTONIC, @ts)=0 then
                   begin
                   Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 1000000);
                   exit;
                   end;
               {$ENDIF}
                fpgettimeofday(@tp, nil);
                Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_usec div 1000);
              end;

              Способ №3 — использование функций QueryPerformanceCounter и QueryPerformanceFrequency

              Платформы: Windows

              Использовать функции можно, подключив в uses модуль windows. Соответственно, под Linux метод использовать невозможно, а посмотреть реализацию способа в Windows можно в предыдущей статье про точное измерение времени выполнения операций.

              Способ №4 — когда разбираться с функциями лень. Используем компонент TEpikTimer

              По аналогии с классом TStopwatch из Delphi, компонент TEpikTimer дает нам широкие возможности по определению времени, затраченного на выполнение какой-либо операции. В принципе, этим компонентом я обычно и пользуюсь.

              Чтобы установить компонент, заходим в меню «Пакет — Установить/удалить пакеты»

              В списке «Доступные для установки» ищем пакет под названием etpackage_dsgn

              Жмем кнопку «Установить выбранное» под списком и, потом, «Сохранить и перезапустить IDE». В новом окне жмем «Продолжить», Lazarus пересоберется и на вкладке System появится новый компонент TEpikTimer:

              У компонента есть множество полезных функций, позволяющих измерить точное время выполнения операции в Lazarus, я продемонстрирую только одну из них.

              procedure TForm1.Button3Click(Sender: TObject);
              begin
                EpikTimer1.Clear; //сбрасываем таймер
                EpikTimer1.Start; //засекаем время
                DoSomething;
                EpikTimer1.Stop;  //останавливаем таймер
                {выводим время выполнения операции в секундах}
                Memo1.Lines.Add(EpikTimer1.Elapsed.ToString);
              end;

              Здесь я вывел время выполнения операции в секундах. Также EpikTimer умеет выводить время в различных форматах.

              Помимо представленных выше способов, вы можете также воспользоваться и другими способами измерения точного времени выполнения операции в Lazarus и Free Pascal, например компонентом TJclCounter от JEDI, однако, в любом случае, эти компоненты будут использовать один из способов, рассмотренных выше, как это делает EpikTimer. 

              4
              2
              голоса

              Рейтинг статьи

              уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

              Понравилась статья? Поделить с друзьями:
            • Как правильно составить заявление в суд на уменьшение алиментов
            • Как найти свою убежавшую кошку
            • Терминал как исправить время
            • Как найти удобную кровать
            • Как найти градусную меру меньшего угла четырехугольника