Feel Good.

13 марта 2012

Stopwatch. Новые идеи.

Как-то давно я написал статью "Пишем обертку для Stopwatch", в которой рассказал как удобно было бы использовать стандартный класс Stopwatch из System.Diagnostics, сделав для него IDisposable обертку. И вот наконец, у меня появились новые идеи и свободное время и я решил вернуться к этой теме и немного ее доработать.

1. API. Я решил сделать единую точку входа - статический класс StopwatchManager со статическим методом Start. Все очень просто и понятно:

using (StopwatchManager.Start(elapsed => Console.WriteLine("Elapsed: {0}", elapsed)))
{
Thread.Sleep(2345);
}

2. Регионы (new!). Как часто Вам требовалось узнать не только текущее время выполнения блока, а например, еще и общее или суммарное время выполнения, либо узнать сколько раз блок выполнился, либо узнать минимальное, максимальное или среднее время выполнения? Теперь это стало проще благодаря именованным регионам:

using (StopwatchManager.Start("region", elapsed => 
Console.WriteLine("Third. " +
"Elapsed: {0}, " +
"Total: {1}, " +
"Count: {2}, " +
"Min: {3}, " +
"Max: {4}, " +
"Avg: {5}",
elapsed.Current,
elapsed.Total,
elapsed.Count,
elapsed.Min,
elapsed.Max,
elapsed.Avg
)))
{
Thread.Sleep(500);
}

Здесь “region” это идентификатор региона, задав его мы указываем, что хотим собирать статистику для помеченного блока кода. В статистику входят: Current – текущее, Avg - среднее, Min – минимальное, Max – максимальное, Total – общее время выполнения, Count – количество прогонов.


3. NuGet package (new!). Для удобства использования, я собрал все это в NuGet пакет, который можно скачать здесь, или через консоль:

PM> Install-Package Devme.Diagnostics


Исходники
Wiki

Всем приятного использования!

3 комментария:

  1. Каждый раз писать лямбду с консолью муторно. Нельзя ли в StopwatchManager'е сделать нечто подобное StopwatchManager.LogToConsole(), и добавить перегруженных методов, чтобы выводили сообщение по-умолчанию?

    ОтветитьУдалить
  2. Да, было бы удобно в некоторых случаях, я подумаю над этим.

    Но с другой стороны можно заготовить эти handler-ы в каком-нибудь static классе:
    static class Helper
    {
    public static void LogToConsole(TimeSpan t) {...}
    }

    И использовать:
    StopwatchManager.Start(Helper.LogToConsole)

    ОтветитьУдалить
  3. Думаю, StopwatchManager.Start(Helper.LogToConsole) - это излишнее усложнение API. Хорошее развитое (fluent) АPI нужно только для сложных случаев, вроде регистрациии в контейнере. А здесь важна простота использованя. В общем, как бы сделал я - добавил бы две перегрузки для метода:
    using (StopwatchManager.Start()) - логгирует время в консоль без лишних разговоров.
    using (StopwatchManager.Start("Elapsed: {0}", elapsed)) - задаём формат и данные, а дальше в консоль без лишних разговоров.

    ОтветитьУдалить