Точное время измерения выполнения операции в Delphi может пригодится во многих случаях, начиная от самого простого — показать пользователю время, затраченное на выполнение длительной операции (здесь, кстати, высокая точность нужна редко) и, заканчивая, ситуациями, когда в целях оптимизации программы нам необходимо выявить в программе наиболее «узкие» места в которых программа «застревает» на длительный промежуток времени. В основном, последняя ситуация характерна при разработке программ, использующих и обрабатывающих большие массивы данных, когда скорость выполнения операций выходит, если не на первое, то на одно из первых мест в требованиях к приложению.
Есть несколько способов узнать время выполнения операций в Delphi и все эти способы, в принципе, рассмотрены как в Сети, так и моем блоге. Поэтому представленная ниже статья — это лишь объединение всех возможных способов измерения времени в Delphi и опытный Delphi-программист здесь врядли встретит что-то новое для себя.
Простой способ замерить скорость работы кода в python
Способ №1 — самый простой. Используем функцию Now()
Самый простейший и наименее точный способ измерить время, затраченное на выполнение какой-либо операции в Delphi — воспользоваться функцией Now() из модуля System.SysUtils .
Исходный код может выглядеть, например, так:
uses System.DateUtils; . var Start, Stop: TDateTime; Elapsed: int64; begin Start:=Now; //засекли начало выполнения операции DoSomething;//выполняем что-либо Stop:=Now; //засекли окончание выполнения операции Elapsed:=SecondsBetween(Start, Stop);//время в секундах end; |
uses System.DateUtils; . var Start, Stop: TDateTime; Elapsed: int64; begin Start:=Now; //засекли начало выполнения операции DoSomething;//выполняем что-либо Stop:=Now; //засекли окончание выполнения операции Elapsed:=SecondsBetween(Start, Stop);//время в секундах end;
Вполне вероятно, что у вас может возникнуть резонный вопрос: почему я использовал в примере SecondsBetween() , а не, например, MilliSecondsBetween() для большей точности? Сделал я это, опираясь исключительно, на описание функции Now() в официальной справке по Delphi, которая гласит следующее: » Несмотря на то, что в TDateTime могут передаваться миллисекунды, Now() имеет точность до ближайшей секунды «. То есть, если использовать Now() , то определять интервал времени с точностью до миллисекунд — не имеет смысла.
Способ №2 — используем Windows API. Функция GetTickCount().
Функция GetTickCount() не имеет параметров и возвращает количество миллисекунд, прошедших с момента запуска системы. Судя по официальной справке Microsoft, разрешение функции GetTickCount() ограничено разрешением системного таймера, которое обычно находится в диапазоне от 10 до 16 миллисекунд. При этом, счётчик миллисекунд будет обнулен, если система запущена более 49,7 дней.
В принципе, пример использования этой функции похож на предыдущий:
var Start, Stop: cardinal; Elapsed: cardinal; begin Start:=GetTickCount; //засекли начало выполнения операции DoSomething;//выполняем что-либо Stop:=GetTickCount; //засекли окончание выполнения операции Elapsed:=Stop-Start;//время в миллисекундах end; |
var Start, Stop: cardinal; Elapsed: cardinal; begin Start:=GetTickCount; //засекли начало выполнения операции DoSomething;//выполняем что-либо Stop:=GetTickCount; //засекли окончание выполнения операции Elapsed:=Stop-Start;//время в миллисекундах end;
КАК ИЗМЕРИТЬ ВРЕМЯ ВЫПОЛНЕНИЯ ПРОГРАММЫ, КОДА, МЕТОДА, ФУНКЦИИ, ЗАПРОСА | C# STOPWATCH | C# ПЛЮШКИ
Так, используя функцию GetTickCount() мы можем засечь время выполнения операции в Delphi с точностью до миллисекунды. Если и такая точность Вам не подходит и необходимо измерить интервал времени ещё точнее, то следующий способ — для вас.
Способ №3 — продолжаем использовать Windows API. Функции QueryPerformanceCounter и QueryPerformanceFrequency
QueryPerformanceCounter — извлекает текущее значение счетчика производительности, которое представляет собой метку времени с высоким разрешением ( QueryPerformanceFrequency — извлекает частоту счетчика производительности. Частота счетчика производительности фиксируется при загрузке системы и согласована во всех процессорах,поэтому значение нужно запрашивать только при инициализации приложения, а результат может быть кэширован.
Для того, чтобы воспользоваться этими функциями для отсчёта интервала времени, затраченного на выполнение какой-либо операции в Delphi нам необходимо оформить исходный код, например, таким образом:
var iCounterPerSec: TLargeInteger; T1, T2: TLargeInteger; //значение счётчика ДО и ПОСЛЕ операции begin QueryPerformanceFrequency(iCounterPerSec);//определили частоту счётчика QueryPerformanceCounter(T1); //засекли время начала операции DoSomething; //выполнили что-то QueryPerformanceCounter(T2);//засекли время окончания ShowMessage(FormatFloat(‘0.0000’, (T2 — T1)/iCounterPerSec) + ‘ сек.’);//вывели количество секунд на выполнение операции end; |
var iCounterPerSec: TLargeInteger; T1, T2: TLargeInteger; //значение счётчика ДО и ПОСЛЕ операции begin QueryPerformanceFrequency(iCounterPerSec);//определили частоту счётчика QueryPerformanceCounter(T1); //засекли время начала операции DoSomething; //выполнили что-то QueryPerformanceCounter(T2);//засекли время окончания ShowMessage(FormatFloat(‘0.0000’, (T2 — T1)/iCounterPerSec) + ‘ сек.’);//вывели количество секунд на выполнение операции end;
С полученными значениями T1 и T2 можно «играться» как угодно, например, выводить отдельно минуты/секунды/миллисекунды и т.д. тут всё зависит от ваших потребностей и желаний, я же показал наиболее простой пример использования счётчика с высоким разрешением в Delphi.
Способ №4 — используем возможности Delphi. Модуль System.Diagnostics
Модуль этот появился в Delphi уже достаточно давно (могу ошибаться, но, по-моему с Delphi XE-XE2). В модуле представлена всего одна запись ( record ) — TStopwatch , которая является ни чем иным, как удобной «обёрткой» для использования таймеров высокого разрешения из примера выше. Судя по достаточно скромной справке, TStopwatch использует функциональные возможности, зависящие от операционной системы, для получения доступа к таймерам с высоким разрешением, если они доступны. Если таймеры с высоким разрешением в ОС недоступны, то используются обычные таймеры.
Несмотря на то, что TStopwatch — это запись, для корректного использования всё же необходимо вызывать метод Create или StartNew .
Описание TStopwatch следующее:
TStopwatch = record strict private class var FFrequency: Int64; class var FIsHighResolution: Boolean; class var TickFrequency: Double; strict private FElapsed: Int64; FRunning: Boolean; FStartTimeStamp: Int64; function GetElapsed: TTimeSpan; function GetElapsedDateTimeTicks: Int64; function GetElapsedMilliseconds: Int64; function GetElapsedTicks: Int64; class procedure InitStopwatchType; static; public class function Create: TStopwatch; static; class function GetTimeStamp: Int64; static; procedure Reset; procedure Start; class function StartNew: TStopwatch; static; procedure Stop; property Elapsed: TTimeSpan read GetElapsed; property ElapsedMilliseconds: Int64 read GetElapsedMilliseconds; property ElapsedTicks: Int64 read GetElapsedTicks; class property Frequency: Int64 read FFrequency; class property IsHighResolution: Boolean read FIsHighResolution; property IsRunning: Boolean read FRunning; end; |
TStopwatch = record strict private class var FFrequency: Int64; class var FIsHighResolution: Boolean; class var TickFrequency: Double; strict private FElapsed: Int64; FRunning: Boolean; FStartTimeStamp: Int64; function GetElapsed: TTimeSpan; function GetElapsedDateTimeTicks: Int64; function GetElapsedMilliseconds: Int64; function GetElapsedTicks: Int64; class procedure InitStopwatchType; static; public class function Create: TStopwatch; static; class function GetTimeStamp: Int64; static; procedure Reset; procedure Start; class function StartNew: TStopwatch; static; procedure Stop; property Elapsed: TTimeSpan read GetElapsed; property ElapsedMilliseconds: Int64 read GetElapsedMilliseconds; property ElapsedTicks: Int64 read GetElapsedTicks; class property Frequency: Int64 read FFrequency; class property IsHighResolution: Boolean read FIsHighResolution; property IsRunning: Boolean read FRunning; end;
- Свойство IsHighResolution указывает, основан ли таймер на счетчике производительности с высоким разрешением.
- Метод Start() начинает измерять прошедшее время.
- Метод Stop() останавливает измерение прошедшего времени.
- Свойство ElapsedMilliseconds получает общее истекшее время в миллисекундах.
- Свойство Elapsed получает истекшее время в виде TTimeSpan .
Воспользоваться возможностями TStopwatch также достаточно просто, например, так:
uses System.Diagnostics; . var SW: TStopwatch; begin SW:=TStopwatch.StartNew; SW.Start; DoSomething; SW.Stop; ShowMessage(SW.Elapsed.TotalMinutes.ToString); end; |
uses System.Diagnostics; . var SW: TStopwatch; begin SW:=TStopwatch.StartNew; SW.Start; DoSomething; SW.Stop; ShowMessage(SW.Elapsed.TotalMinutes.ToString); end;
В представленном выше примере мы воспользовались TStopwatch и вывели количество минут (с дробной частью), пошедших на выполнение какой-то операции. В целом же, используя возможность TStopwatch.Elapsed можно выводить любые значения, ограниченные лишь возможностями TTimeSpan (см. справку).
Подведем итог
Итак, чтобы измерить точное время выполнения операции в Delphi, необходимо, прежде всего определиться с тем какая точность Вас устроит? Если достаточно, чтобы интервал времени определялся с точностью до секунды, то достаточно воспользоваться обычной, давно известной функцией Now() . Да, точность самая низкая, но, зато — просто.
Если ваше требование к точности измерения времени ограничивается миллисекундой — используйте GetTickCount() : просто, достаточно надежно (только, если вы не планируете измерять интервал времени больше 49,7 дней).
Если же требуется использовать самые точные методы измерения времени на выполнение операции, то тут либо связка функций QueryPerformanceCounter() и QueryPerformanceFrequency() , либо более удобный способ — использовать TStopwatch из модуля System.Diagnostics .
02.2018 | ||
Источник: www.interface.ru Как замерить время выполнения программыОдним из важнейших ресурсов программного продукта является время выполнения его программного кода. Оно, наряду с такими показателями, как функциональные возможности, надежность, практичность, сопровождаемость и мобильность, определяет уровень качества программного продукта. В работе рассмотрен метод измерения времени выполнения программного кода с помощью таймера высокой точности High Precision Event Timer (HPET). Описан класс Stopwatch библиотеки классов FCL каркаса Framework, который работает с HPET и предоставляет удобный набор средств, используемых для измерения времени. Описаны специальные проблемно-ориентированные методы класса Stopwatch технологии .Net в операционной системе Microsoft Windows. Основным преимуществом класса Stopwatch является более точное измерение временных интервалов при наличии таймера высокой точности HPET. В качестве эксперимента исследуется время обработки массивов классов Array, List и ArrayList. Для данных классов исследуется: время формирования элементов массивов; время работы методов Reverse, которые переставляют элементы массивов в обратном порядке; время работы методов Sort, которые сортируют элементы массивов. Приведен программный код на объектно-ориентированном языке программирования C# для платформы .NET Framework.
методы класса 1. Лохматов С.Ю., Светлов С.В., Калач Г.П. Методы измерения времени работы программы // Современные научные исследования и инновации. 2017. № 5 [Электронный ресурс]. URL: http://web.snauka.ru/issues/2017/05/83188 (дата обращения: 11.03.2021). 2. Хашковскии В.В., Лутай В.Н., Юрченко В.В. Сравнительная оценка времени выполнения программ на различных платформах / Известия ЮФУ. Техн. науки. 2009. С. 176–180. 4. ГОСТ ИСО/МЭК 9126-2001 «Информационные технологии. Оценка программной продукции. Характеристики качества и руководства по их применению». Минск: Евразийский совет по стандартизации, метрологи и сертификации, 2006. 13 с. 5. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644904(v=vs.85).aspx (дата обращения: 11.03.2021). 6. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644905(v=vs.85).aspx (дата обращения: 11.03.2021). 7. Карчевская М.П., Рамбургер О.Л. Измерение времени выполнения программного кода в ОС Windows с использованием ИСР Lazarus // Задачи обработки больших данных в авиации: материалы II Всероссийской научно-практической конференции «Свободный полет – 2015». Жуковский. Уфа, 2016. С. 127–133. 8. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.diagnostics.stopwatch(v=vs.110).aspx (дата обращения: 11.03.2021). 9. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.timespan(v=vs.110).aspx (дата обращения: 11.03.2021). 10. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.array(v=vs.110).aspx (дата обращения: 11.03.2021). 11. Библиотека документации для разработчиков под ОС MS Windows. [Электронный ресурс]. URL: https://msdn.microsoft.com/ru-ru/library/system.collections.arraylist(v=vs.110).aspx (дата обращения: 11.03.2021). 12. Карчевская М.П., Кузьмина Е.А., Рамбургер О.Л., Смирнова Е.А. Технология программирования на С#: учебное пособие. Уфа: РИК УГАТУ, 2016. 278 с. 13. Карчевская М.П., Рамбургер О.Л. Технология программирования на VB.NET: учебное пособие. Уфа: УГАТУ, 2014. 225 с. В современной программной инженерии в процессе проектирования, написания и отладки программных продуктов нередко приходится решать вопросы, связанные с определением и последующей оптимизацией времени выполнения программного кода [1]. Не меньший интерес представляют вопросы, связанные с оценкой времени выполнения того или иного кода, написанного на различных языках программирования и на различных компьютерных платформах [2]. Определение времени выполнения программного кода критично: – для приложений, обрабатывающих данные в режиме реального времени, например приложений, реализующих функции управления техническими устройствами; – при решении инженерных и научно-технических задач, в которых производятся сложные длительные вычисления, а процессорное время дорого и ограничено, например в задачах проектирования и расчета сложных технических объектов; – при разработке программ, работающих с аппаратной частью компьютеров, например драйверов для различных устройств; – для процессов обработки больших данных, требующих значительных временных затрат, например при проведении маркетинговых исследований; – при генерации страниц в web-приложениях, в которых время критично для пользователя и напрямую связано с производительностью серверов; – для процессов измерения скорости передачи данных в коммуникационных системах; – при проведении всевозможных тестирований и др. В процессе разработки программного обеспечения нередко возникает необходимость отладки фрагментов кода, критичных по времени исполнения, для выявления «узких мест» выполнения программы, потребляющих чрезмерное количество ресурсов [3]. Время выполнения программного кода – это один из важнейших ресурсов, определяющих уровень качества программного продукта, наряду с такими показателями, как функциональные возможности, надежность, практичность, сопровождаемость и мобильность [4]. Оптимизация производительности программного продукта путем сокращения времени выполнения программного кода особенно важна, если он разрабатывается в расчете на длительный жизненный цикл и массовое использование при высоких требованиях к его качеству. Цель исследования– измерение времени выполнения программного кода c использованием методов класса Stopwatch технологии .Net в ОС Windows для оценки качества программного продукта. Материалы и методы исследования Измерение времени выполнения программного кода будем выполнять в ОС Windows (Windows 10 Pro, 64-разрядная), как в одной из самых распространённых в настоящее время операционных систем. В качестве системы программирования используем Microsoft Visual Studio 2013 и язык программирования C#. Описанные ниже возможности измерения времени можно одинаково использовать как в Visual C# .NET, так и Visual Basic .NET, в Visual C++ .NET и Visual J# .NET. Для проведения измерений применим специальные проблемно-ориентированные методы класса Stopwatch на технологической платформе .Net. Класс Stopwatch основан на HPET (High Precision Event Timer – таймер событий высокой точности). Таймер HPET разработан Microsoft с целью устранения проблем с измерением времени выполнения того или иного программного кода. Частота таймера HPET (минимум 10 МГц) не меняется во время работы системы. Каждая версия OS Windows сама определяет, с помощью каких устройств следует реализовать этот таймер. Существует несколько способов измерения интервалов времени в ОС Windows. Например, функция timeGetTime возвращает системное время в миллисекундах достаточно точно, однако работает медленно из-за многочисленных промежуточных вызовов и преобразований. Функция GetTickCount работает быстро, но имеет невысокую точность 15 мс (для Windows XP), так как использует прерывания, генерируемые часами реального времени компьютера. Более точный метод измерения времени в ОС Windows – использование пары функций QueryPerformanceCounter [5] и QueryPerformanceFrequency [6]. Функция QueryPerformanceCounter возвращает текущее значение в тиках, а функция QueryPerformanceFrequency возвращает частоту счетчика производительности. Эти функции работают быстро и имеют высокую точность, так как используют таймер высокой точности High Precision Event Timer (HPET). Временной промежуток между «тиками» этого таймера меньше 1 мс, что позволяет производить достаточно точные измерения [7]. В библиотеке классов FCL каркаса Framework имеется класс Stopwatch [8], который также работает с таймером высокого точности High Precision Event Timer и предоставляет удобный набор средств, используемых для измерения времени. Публичный API класса Stopwatch инкапсулирует следующий набор свойств (табл. 1) и методов (табл. 2). Свойства публичного API класса Stopwatch Возвращает общее затраченное время, измеренное текущим экземпляром Источник: top-technologies.ru Delphi: как измерить точное время выполнения операции?Точное время измерения выполнения операции в Delphi может пригодится во многих случаях, начиная от самого простого – показать пользователю время, затраченное на выполнение длительной операции (здесь, кстати, высокая точность нужна редко) и, заканчивая, ситуациями, когда в целях оптимизации программы нам необходимо выявить в программе наиболее “узкие” места в которых программа “застревает” на длительный промежуток времени. В основном, последняя ситуация характерна при разработке программ, использующих и обрабатывающих большие массивы данных, когда скорость выполнения операций выходит, если не на первое, то на одно из первых мест в требованиях к приложению. Есть несколько способов узнать время выполнения операций в Delphi и все эти способы, в принципе, рассмотрены как в Сети, так и моем блоге. Поэтому представленная ниже статья – это лишь объединение всех возможных способов измерения времени в Delphi и опытный Delphi-программист здесь врядли встретит что-то новое для себя.
Способ №1 – самый простой. Используем функцию Now()Самый простейший и наименее точный способ измерить время, затраченное на выполнение какой-либо операции в Delphi – воспользоваться функцией Now()из модуля System.SysUtils. Исходный код может выглядеть, например, так: Источник: darksf.ru |