Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Модуль для удобного замера точных интервалов времени / 8 сообщений из 8, страница 1 из 1
30.06.2020, 00:39
    #39974333
DmSer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
Разработал модуль для удобного замера точных интервалов времени.
Ссылка на модуль: https://github.com/loginov-dmitry/multithread/blob/master/CommonUtils/TimeIntervals.pas

Основу модуля составляет record TTimeInterval, в котором имеется метод Start для запуска замера, Stop для останова замера и набор методов ElapsedXXX, позволяющих определить, сколько прошло времени с начала замера. Можно использовать в Delphi 2007 и более новых версиях. Текущая реализация - только под Windows.

Вот объявление структуры TTimeInterval:
Код: pascal
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.
31.
32.
33.
34.
35.
36.
37.
type
  { TTimeInterval is designed to accurately measure time,
     passed after the start of measurement.
     Attention! Microsecond measurements
     performed with an error of several microseconds (despite
     using the variable PerformanceIgnoredTicks }
  TTimeInterval = record
  private
    FStartCounter: Int64;
    FIsRunning: Boolean;
    FElapsedTicks: Int64;
  public
    // Starts measuring
    procedure Start;

    // Finishes measuring. Updates the FElapsedTicks field. After the Stop method
    // is called, the ElapsedXXX methods will return the value stored in FElapsedTicks
    procedure Stop;

    // Returns the number of milliseconds after the start of measurement
    function ElapsedMilliseconds(AStartNew: Boolean = False): Int64;

    // Returns the number of microseconds after the start of measurements
    function ElapsedMicroseconds(AStartNew: Boolean = False): Int64;

    // Returns the number of seconds after the start of measurement
    function ElapsedSeconds(AStartNew: Boolean = False): Double;

    // Returns the number of ticks from the beginning of measurements
    function ElapsedTicks(AStartNew: Boolean = False): Int64;

    // Returns the time (TDateTime) elapsed since the start of measurement
    function ElapsedTime(AStartNew: Boolean = False): TDateTime;

    // Returns True if measurements are running.
    property IsRunning: Boolean read FIsRunning;
  end;



Как видно, результат замера времени можно получить в разных форматах: в миллисекундах, в микросекундах, в секундах, в отсчётах высокочастотного таймера, а также в стандартном TDateTime.

Пример использования:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.Button2Click(Sender: TObject);
var
  p: TTimeInterval;
begin
  p.Start;
  Sleep(100);
  ShowMessageFmt('%s', [FormatDateTime('hh:nn:ss.zzz', p.ElapsedTime)]);
end;



Также можно остановить замер с помощью метода Stop, а вызов метода ElapsedXXX выполнить позже, в удобное время.
Высокая точность измерения (практически до микросекунды) обеспечивается за счёт запоминания длительности вызова QueryPerformanceCounter в переменной PerformanceIgnoredTicks (она учитывается при останове замера).

Кроме того, в модуле TimeIntervals имеется ещё одна структура, упрощающая логирование длительности серии операций: TTimeIntervalEvents. Пример её использования:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure TForm1.Button1Click(Sender: TObject);
var
  p: TTimeIntervalEvents;
begin
  p.StartEvent('Этап 1');
  Sleep(1);
  p.StopEvent('Этап 1');

  p.StartEvent('Этап 2');
  Sleep(20);
  p.StopEvent('Этап 2');

  ShowMessage(p.GetEventsAsString([eoWriteStartTime, eoWriteAllTime,
    eoUseMicroSec, eoWriteFromStart, eoWriteBegTime, eoWriteEndTime, eoWriteDate]));
  //ShowMessage(p.GetEventsAsString([eoUseMicroSec]));
end;



Я считаю, что данное решение более удобное и более продуманное, чем структура "секундомер", встроенная в современные версии Delphi (имеется ввиду TStopWatch из System.Diagnostics). TStopWatch - это, на мой взгляд, очень слабо продуманное решение, которое зачем-то срочно (с пивом за вечер) понадобилось сделать. Я сужу по его реализации в Delphi 10.3 (может в 10.4 что-то и улучшили).
Какие лично у меня замечания к TStopWatch:
1. Является секундомером, однако секунды измерять не умеет.
2. Ничего кроме миллисекунд (и неких условных единиц) не возвращает.
3. Не является интуитивно понятным. Думаете метода Start там достаточно для запуска секундомера? Нифига! Start там - это лишь продолжение замера, который был поставлен на паузу с помощью метода Stop. Stop - это не останов замера (как кажется из названия)! Это лишь постановка на паузу.
3.1 Для начала замера времени обязательно нужно вызвать метод TStopWatch.StartNew.
4. Какое отношение вообще секундомер имеет к диагностике? Могли бы сделать секундомер в виде компонента с циферками, было бы более логично!

Спасибо за внимание! :)
...
Рейтинг: 0 / 0
30.06.2020, 08:43
    #39974393
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
DmSer, очень хотелось бы микро и нано секунды
...
Рейтинг: 0 / 0
30.06.2020, 09:05
    #39974404
DmSer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
cptngrb
DmSer, очень хотелось бы микро и нано секунды

Насколько я понимаю, в наносекундах умеют измерять профилировщики. У меня нет задачи сделать профилировщик.
...
Рейтинг: 0 / 0
15.07.2020, 09:36
    #39979737
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
У меня для этих целей используется класс TOSTime:
https://github.com/d-mozulyov/Tiny.Library/blob/master/Tiny.Types.pas#L765

И в качестве основы для винды была взята LocalFileTimeToFileTime
Т.к. самая быстрая и, судя по документации, имеет высокую точность

Я ещё не разбирался, но вроде бы она работает с большой гранулярностью
Не знаешь, можно ли, получая QueryPerformanceCounter, преобразовывать его к UTC?
Логически напрашивается иметь какую-то переменную-смещение. Но во-первых, QueryPerformanceCounter скорее всего быстро переполнится. Во-вторых, я слышал, что он разный на разных ядрах. Что ты по этому поводу думаешь?

P.S. Поскольку тебе интересны потоки, возможно тебе будет интересен TaggedPtr для реализации lock-free контейнеров
...
Рейтинг: 0 / 0
15.07.2020, 13:37
    #39979911
Bred eFeM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
...
Рейтинг: 0 / 0
15.07.2020, 13:45
    #39979918
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
Bred eFeM,

Пишут, поддержка с Windows 8
...
Рейтинг: 0 / 0
15.07.2020, 21:49
    #39980168
DmSer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
SOFT FOR YOU
Но во-первых, QueryPerformanceCounter скорее всего быстро переполнится. Во-вторых, я слышал, что он разный на разных ядрах. Что ты по этому поводу думаешь?


Я реализовал модуль TimeIntervals и больше не думал о QueryPerformanceCounter. Чувствую себя нормально! :)

SOFT FOR YOU

P.S. Поскольку тебе интересны потоки, возможно тебе будет интересен TaggedPtr для реализации lock-free контейнеров


Предпочитаю использовать готовые контейнеры, а не создавать свои. До сих пор на работе старый Delphi, но если обновят, то попробую твои словари. Как-то год назад делал тесты, они показали наибольшую производительность среди других решений. Правда, была какая-то проблема с перечислениями значений в цикле for in.
...
Рейтинг: 0 / 0
15.07.2020, 22:18
    #39980176
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модуль для удобного замера точных интервалов времени
DmSer,

Да, с for in была какая-то ошибка, сейчас исправлено
Насчёт контейнеров... ну они же не обязательно дженерики )
Условно говоря лок-фри стек реализовать без TaggedPtr сложно
Библиотека (кроме дженериков) работает начиная с Delphi 7
Там и другие плюшки есть )
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Модуль для удобного замера точных интервалов времени / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]