Измерить время выполнения в C#

Я хочу измерить выполнение фрагмента кода, и мне интересно, какой лучший метод это сделать?

Вариант 1:

DateTime StartTime = DateTime.Now;

//Code

TimeSpan ts = DateTime.Now.Subtract(StartTime);
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
2: использование системы.Диагностика;
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();

    //Code

    stopWatch.Stop();
    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine(elapsedTime, "RunTime");

это не просто для бенчмаркинга, его фактически частью заявки. Время, необходимое для выполнения функции, является релевантными данными. Однако он не должен быть атомарным или сверхточным.

какой вариант лучше для производственного кода, или кто-нибудь еще использует что-то другое и, возможно, лучше?

8 ответов


на Stopwatch класс специфически конструирован для того чтобы измерить истекшее время и может (если доступный на вашем оборудовании) обеспечить хорошие степень детализации/точность используя основной высокочастотный таймер оборудования. Так что это кажется лучшим выбором.

на IsHighResolution собственность смогите быть использовано для того чтобы определить ли высокое время разрешения доступно. Согласно документации, этот класс предлагает оболочку на "наилучших доступных" API Win32 для точного времени:

в частности,


не только StopWatch более точно, но и это DateTime.Now даст неправильные результаты в некоторых обстоятельствах.

рассмотрим, что происходит во время перехода на летнее время, например-с помощью DateTime.Now может фактически дать отрицательный ответ!


Я обычно использую StopWatch для такого рода ситуации.

С MSDN страницы:

секундомер

предоставляет набор методов и свойства, которые можно использовать для точно измерьте прошедшее время.

в следующем посте я использую его для сравнения времени выполнения LINQ vs PLINQ:

параллельный LINQ (PLINQ) с Visual Studio 2010


ни один не повредит производительности, потому что вы говорите, что это не так важно. Секундомер кажется более подходящим - вы только вычитаете время от времени, а не одну дату от другой. Дата материал занимает немного больше памяти и времени процессора, чтобы иметь дело. Есть также способы сделать код чище, если вы планируете повторно использовать его в нескольких местах. Перегрузка using приходит на ум. Я буду искать пример. ОК, код украден от:

http://stevesmithblog.com/blog/great-uses-of-using-statement-in-c/

public class ConsoleAutoStopWatch : IDisposable
{
    private readonly Stopwatch _stopWatch;

    public ConsoleAutoStopWatch()
    {
        _stopWatch = new Stopwatch();
        _stopWatch.Start();
    }

    public void Dispose()
    {
        _stopWatch.Stop();
        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, "RunTime");
    }
}

private static void UsingStopWatchUsage()
{
    Console.WriteLine("ConsoleAutoStopWatch Used: ");
    using (new ConsoleAutoStopWatch())
    {
        Thread.Sleep(3000);
    }
}

оба, вероятно, будут соответствовать вашим потребностям, но я бы сказал, использовать StopWatch. Почему? Потому что он предназначен для той задачи, которую ты выполняешь.

У вас есть один класс, который построен для возврата текущей даты / времени, который, как это происходит, может использоваться для синхронизации вещей, и у вас есть один класс, специально разработанный для синхронизации вещей.

в этом случае различия действительно существуют, только если вам нужна точность миллисекунды (в этом случае StopWatch точнее), но в целом Принципал если инструмент существует специально для задачи, которую вы ищете, то он лучше использовать.


У меня есть небольшой класс, чтобы делать такие вещи ad hoc. Он использует класс секундомера - C# micro perfomance тестирование.

например.

var tester = new PerformanceTester(() => SomeMethod());
tester.MeasureExecTime(1000);
Console.Writeline(string.Format("Executed in {0} milliseconds", tester.AverageTime.TotalMilliseconds));

использовать ниже код

DateTime dExecutionTime;
dExecutionTime = DateTime.Now;
      TimeSpan span = DateTime.Now.Subtract(dExecutionTime);
                  lblExecutinTime.Text = "total time taken " +   Math.Round(span.TotalMinutes,2) + " minutes .   >>---> " + DateTime.Now.ToShortTimeString();

Я взял ответ Хэмиша, упростил его и сделал его немного более общим, если вам нужно войти в другое место:

public class AutoStopWatch : Stopwatch, IDisposable {

    public AutoStopWatch() {
        Start();
    }

    public virtual void Dispose() {
        Stop();
    }
}

 public class AutoStopWatchConsole : AutoStopWatch {

    private readonly string prefix;

    public AutoStopWatchConsole(string prefix = "") {
        this.prefix = prefix;
    }

    public override void Dispose() {
        base.Dispose();

        string format = Elapsed.Days > 0 ? "{0} days " : "";
        format += "{1:00}:{2:00}:{3:00}.{4:00}";

        Console.WriteLine(prefix + " " + format.Format(Elapsed.Days, Elapsed.Hours, Elapsed.Minutes, Elapsed.Seconds, Elapsed.Milliseconds / 10));
    }
}

private static void Usage() {

    Console.WriteLine("AutoStopWatch Used: ");
    using (var sw = new AutoStopWatch()) {
        Thread.Sleep(3000);

        Console.WriteLine(sw.Elapsed.ToString("h'h 'm'm 's's'"));
    }

    Console.WriteLine("AutoStopWatchConsole Used: ");
    using (var sw = new AutoStopWatchConsole()) {
        Thread.Sleep(3000);
    }

}