Содержание
При разработке различных программ иногда бывает необходимо измерить точное время какой-либо операции, например, узнать сколько времени требуется на загрузку данных из файла, запись в базу данных и так далее. Сегодня мы рассмотрим то, как измерить время выполнения операции в C#, используя стандартные средства и возможности языка.
System. Diagnostics
Пространство имен System.Diagnostics содержит классы, позволяющие нашим приложениям взаимодействовать с журналами событий, системными процессами и счётчиками производительности. В числе прочего, это пространство имен содержит класс под названием Stopwatch, который можно в своих приложениях C# использовать для точного измерения затраченного времени. Именно об этом классе мы сегодня и поговорим.
Простой пример использования Stopwatch
Для начала, рассмотрим простой пример использования класса Stopwatch для измерения затраченного времени на выполнение операции.
namespace StopwatchExample
{
class Program
{
static void Main(string[] args)
{
//создаем объект
Stopwatch stopwatch = new Stopwatch();
//засекаем время начала операции
stopwatch.Start();
//выполняем какую-либо операцию
for (int i = 0; i < 10001; i++)
{
Console.WriteLine(i);
}
//останавливаем счётчик
stopwatch.Stop();
//смотрим сколько миллисекунд было затрачено на выполнение
Console.WriteLine(stopwatch.ElapsedMilliseconds);
}
}
}
Чтобы измерить время выполнения операции в C# нам необходимо выполнить несколько простых шагов:
- Создать объект класса
Stopwatch; - Выполнить метод
Start()для того, чтобы засечь время начала операции; - Выполнить метод
Stop()для того, чтобы засечь время окончания операции; - Воспользоваться одним из свойств объекта для получения данных о затраченном на выполнение операции времени.
В примере использовано свойство ElapsedMilliseconds, которое позволяет получить количество миллисекунд, затраченных на выполнение операции. Рассмотрим какие ещё есть свойства и методы у класса Stopwatch.
Stopwatch
Свойства Stopwatch
Elapsed
Свойство Elapsed позволяет получить общее затраченное время, измеренное текущим экземпляром класса Stopwatch. Описание свойства выглядит следующим образом:
public TimeSpan Elapsed { get; }
Свойство возвращает объект типа TimeSpan — интервал времени, используя который, можно получить время выполнения операции в удобном для вас виде. Например,
//получаем объект TimeSpan
TimeSpan ts = stopwatch.Elapsed;
// Создаем строку, содержащую время выполнения операции.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime);
ElapsedMilliseconds
Свойство ElapsedMilliseconds позволяет получить общее затраченное время, измеренное текущим экземпляром класса Stopwatchв миллисекундах. В примере использования класса Stopwatch выше продемонстрировано использование этого свойства.
Elapsed Ticks
Свойство Elapsed позволяет получить общее время выполнение операции в тактах таймера, измеренное текущим экземпляром Stopwatch. Такт — это наименьшая единица времени, которую Stopwatch может измерять таймер. В следующем примере показано использование свойства Elapsed для измерения времени, затраченного на преобразование строки в целое число типа int.
int num;
//создаем объект
Stopwatch stopwatch = new Stopwatch();
//засекаем время начала операции
stopwatch.Start();
num = int.Parse("135");
//останавливаем счётчик
stopwatch.Stop();
Console.WriteLine($"num = {num}");
//смотрим сколько тактов было затрачено на выполнение
Console.WriteLine(stopwatch.ElapsedTicks);
Результатом выполнения этого кода может быть вот такой вывод консоли:
16878
Is Running
Свойство IsRunning позволяет получить значение типа bool, указывающее на то запущен ли в данный момент таймер Stopwatch.
Поля Stopwatch
Класс Stopwatch содержит два статических поля, позволяющих получить сведения о настройках таймера.
Frequency
Поле Frequency содержит частоту таймера в виде количества тактов в секунду.
public static readonly long Frequency;
Это поле удобно использовать вместе со свойством Elapsed для преобразования количества тактов в секунды. Например,
int num;
long freq = Stopwatch.Frequency; //частота таймера
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
num = int.Parse("135");
//останавливаем счётчик
stopwatch.Stop();
double sec = (double)stopwatch.ElapsedTicks / freq; //переводим такты в секунды
Console.WriteLine($"num = {num} \r\n Частота таймера {freq} такт/с \r\n Время в тактах {stopwatch.ElapsedTicks} \r\n Время в секундах {sec}");
Обращу внимание только на то, как происходит перевод тактов в секунды. Учитывая особенности деления целых чисел в C#, для того, чтобы получить конкретное значение секунд нам потребовалось привести одно из значений (в данном случае значение свойства ElapsedTicks) к типу double.
Is High Resolution
Свойство Is указывает, зависит ли таймер Stopwatch от счетчика производительности высокого разрешения (true) или же использует класс DateTime (false).
public static readonly bool IsHighResolution;
Пример использования поля
class Program
{
static void Main(string[] args)
{
DisplayTimerProperties();
}
public static void DisplayTimerProperties()
{
if (Stopwatch.IsHighResolution)
{
Console.WriteLine("Операции рассчитываются с использованием системного счетчика производительности с высоким разрешением.");
}
else
{
Console.WriteLine("Операции рассчитываются с использованием класса DateTime.");
}
long frequency = Stopwatch.Frequency;
Console.WriteLine($" Частота таймера = {frequency}");
long nanosecPerTick = (1000L * 1000L * 1000L) / frequency;
Console.WriteLine($" Таймер работает с точностью до {nanosecPerTick} наносекунд");
}
}
Вывод консоли будет иметь следующий вид:
Частота таймера = 10000000
Таймер работает с точностью до 100 наносекунд
Методы Stopwatch
Рассмотрим основные методы класса Stopwatch, которые мы можем использовать для измерения точного времени выполнения операции в C#.
Start и Stop
Метод Start() запускает или возобновляет работу таймера Stopwatch. В свою очередь, Stop() выполняет противоположную операцию — останавливает работу таймера. Использование этих методов продемонстрировано в самом первом примере из этой статьи.
Start New
Метод Start выполняет сразу несколько операций — он инициализирует новый экземпляр класса Stopwatch, обнуляет счётчик затраченного времени и запускает таймер. То есть, этот метод позволяет немного сократить исходный код программы. Например, код из первого примера можно было бы записать вот так:
Stopwatch stopwatch = Stopwatch.StartNew();//создаем и запускаем таймер
for (int i = 0; i < 10001; i++)
{
Console.WriteLine(i);
}
//останавливаем счётчик
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Reset
Метод Reset() останавливает измерение интервала времени и обнуляет счётчик затраченного времени. Использование Reset() позволяет избежать создания новых экземпляров Stopwatch для измерения времени, затраченного на выполнение нескольких операций в C#.
Stopwatch stopwatch = Stopwatch.StartNew();//создаем и запускаем таймер
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
//останавливаем счётчик
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение
Console.WriteLine($"Первая операция {stopwatch.ElapsedMilliseconds}");
stopwatch.Reset(); //сбросили счётчик
stopwatch.Start(); //запустили счётчик
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i*i);
}
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение
Console.WriteLine($"Вторая операция {stopwatch.ElapsedMilliseconds}");
Restart
Метод Restart() останавливает измерение интервала времени, обнуляет затраченное время и повторно запускает таймер. Таким образом, предыдущий пример можно переписать следующим образом:
Stopwatch stopwatch = Stopwatch.StartNew();//создаем и запускаем таймер
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
//останавливаем счётчик
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение
Console.WriteLine($"Первая операция {stopwatch.ElapsedMilliseconds}");
stopwatch.Restart(); //перезапускаем счётчик
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i*i);
}
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение
Console.WriteLine($"Вторая операция {stopwatch.ElapsedMilliseconds}");
Итого
Класс Stopwatch из пространства имен System. C# позволяет измерить время выполнения операции с точностью до 100 наносекунд в зависимости от того, что используется для работы с интервалами времени — таймер высокого разрешения или же класс DateTime.