Как измерить время выполнения операции в C#

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

При разработке различных программ иногда бывает необходимо измерить точное время какой-либо операции, например, узнать сколько времени требуется на загрузку данных из файла, запись в базу данных и так далее. Сегодня мы рассмотрим то, как измерить время выполнения операции в 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# нам необходимо выполнить несколько простых шагов:

  1. Создать объект класса Stopwatch;
  2. Выполнить метод Start() для того, чтобы засечь время начала операции;
  3. Выполнить метод Stop() для того, чтобы засечь время окончания операции;
  4. Воспользоваться одним из свойств объекта для получения данных о затраченном на выполнение операции времени.

В примере использовано свойство 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 выше продемонстрировано использование этого свойства.

ElapsedTicks

Свойство ElapsedTicks позволяет получить общее время выполнение операции в тактах таймера, измеренное текущим экземпляром Stopwatch. Такт — это наименьшая единица времени, которую Stopwatch может измерять таймер. В следующем примере показано использование свойства ElapsedTicks для измерения времени, затраченного на преобразование строки в целое число типа int.

int num;
//создаем объект
Stopwatch stopwatch = new Stopwatch();
//засекаем время начала операции
stopwatch.Start();

num = int.Parse("135");

//останавливаем счётчик
stopwatch.Stop();
Console.WriteLine($"num = {num}");
//смотрим сколько тактов было затрачено на выполнение
Console.WriteLine(stopwatch.ElapsedTicks);

Результатом выполнения этого кода может быть вот такой вывод консоли:

num = 135

16878

IsRunning

Свойство IsRunning позволяет получить значение типа bool, указывающее на то запущен ли в данный момент таймер Stopwatch.

Поля Stopwatch

Класс Stopwatch содержит два статических поля, позволяющих получить сведения о настройках таймера.

Frequency

Поле Frequency содержит частоту таймера в виде количества тактов в секунду.

public static readonly long Frequency;

Это поле удобно использовать вместе со свойством ElapsedTicks для преобразования количества тактов в секунды. Например,

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.

IsHighResolution

Свойство IsHighResolution указывает, зависит ли таймер 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() выполняет противоположную операцию — останавливает работу таймера. Использование этих методов продемонстрировано в самом первом примере из этой статьи.

StartNew

Метод StartNew() выполняет сразу несколько операций — он инициализирует новый экземпляр класса 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.Diagnostics C# позволяет измерить время выполнения операции с точностью до 100 наносекунд в зависимости от того, что используется для работы с интервалами времени — таймер высокого разрешения или же класс DateTime.

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
guest
2 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии