Вопрос

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

Вариант 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");

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

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

Это было полезно?

Решение

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

То Ishighresolution Property Может использоваться для определения того, доступно ли высокое разрешение. Для документации этот класс предлагает обертку на «лучших доступных» API Win32 для точного времени:

В частности, то Frequency поле и GetTimestamp Метод может быть использован вместо неуправляемых API в Win32 QueryPerformanceFrequency и QueryPerformanceCounter.

Существует подробный фон об этих API Win32 [здесь] и в связанных документах MSDN 2.

Таймер высокого разрешения

Счетчик - это общий термин, используемый в программировании для обозначения переменной увеличения. Некоторые системы включают в себя счетчик производительности высокого разрешения, который обеспечивает время истечения высокого разрешения.

Если в системе существует счетчик производительности высокого разрешения, вы можете использовать QueryPerformanceFrequencyФункция, чтобы выразить частоту, в количестве в секунду. Значение количества зависит от процессора. Например, на некоторых процессорах счет может быть скорость цикла процессорных часов.

То QueryperformanceCounter Функция получает текущее значение счетчика производительности высокого разрешения. Называя эту функцию в начале и в конце раздела кода, приложение, по сути, использует счетчик в качестве таймера высокого разрешения. Например, предположим, что QueryPerformanceFrequency Указывает, что частота счетчика эффективности высокого разрешения составляет 50 000 счетов в секунду. Если приложение вызывает QueryperformanceCounter Непосредственно перед и сразу после того, как раздел кода, который необходимо приурочиться, значения счетчика могут составлять 1500 счетчиков и 3500 счетчиков соответственно. Эти значения будут указывать на то, что 0,4 секунды (2000 счетчиков), прошедшее, когда код выполнен.

Другие советы

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

Подумайте о том, что происходит во время летнего времени, например, - использование DateTime.Now может на самом деле дать отрицательный отвечать!

Я вообще использую StopWatch Для такого рода ситуации.

От MSDN страница:

Секундомер

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

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

Parallel Linq (Plinq) с Visual Studio 2010

Ни один из них не повредит производительности, потому что вы говорите, что это не так критическое. Sprockwatch кажется более уместным - вы со временем вычитаете только время, а не в одну дату с другой. Дата материала требует немного больше памяти и времени процессора. Есть также способы сделать код чище, если вы планируете повторно использовать его в нескольких местах. Перегрузка 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.Он использует класс stopwatch - тестирование производительности 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);
    }

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top