Пример простейшего счетчика производительности - PullRequest
13 голосов
/ 09 октября 2010

Какое наименьшее количество кода C # для запуска и запуска счетчика производительности?

Я просто хочу измерить количество циклов ЦП и / или время между двумя точками в моем коде. Я пролистал всю вафлю в сети, но, похоже, НАМНОГО больше кода, чем необходимо для такой тривиальной задачи. Я просто хочу быстро провести измерение и сконцентрироваться на том, над чем работаю.

Ответы [ 3 ]

30 голосов
/ 09 октября 2010

Я не думаю, что вам нужен счетчик производительности для этого.Вам нужно больше времени, чем вы можете получить от StopWatch ?Это очень точно.

Stopwatch watch = Stopwatch.StartNew();

// Do work

watch.Stop();
// elapsed time is in watch.Elapsed

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

using System;
using System.Diagnostics;
using System.Linq;

static class Test
{
    static void Main()
    {
        var processorCategory = PerformanceCounterCategory.GetCategories()
            .FirstOrDefault(cat => cat.CategoryName == "Processor");
        var countersInCategory = processorCategory.GetCounters("_Total");

        DisplayCounter(countersInCategory.First(cnt => cnt.CounterName == "% Processor Time"));
    }

    private static void DisplayCounter(PerformanceCounter performanceCounter)
    {
        while (!Console.KeyAvailable)
        {
            Console.WriteLine("{0}\t{1} = {2}",
                performanceCounter.CategoryName, performanceCounter.CounterName, performanceCounter.NextValue());
            System.Threading.Thread.Sleep(1000);
        }
    }
}

Конечно, процессу потребуются соответствующие разрешения для доступа к необходимым вам счетчикам производительности.

9 голосов
/ 06 марта 2015

Мне нравится то, что может взять любой блок кода и обернуть его кодом профилирования секундомера для измерения времени, потраченного на его выполнение:

    using System.Diagnostics;
    using System.Threading;

    public static T Profile<T>(Func<T> codeBlock, string description = "")
    {
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();
        T res = codeBlock();
        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        const double thresholdSec = 2;
        double elapsed = ts.TotalSeconds;
        if(elapsed > thresholdSec)
          System.Diagnostics.Debug.Write(description + " code was too slow! It took " +
             elapsed + " second(s).");
        return res;
    }

Тогда назовите это так:

    Profile(() => MyObj.MySlowMethod());

или

    Profile(() => MyObj.MySlowMethod(), "I can explain why");
2 голосов
/ 09 октября 2010

Не существует тривиального способа запустить его в .NET.Тем не менее, самый простой способ, который я нашел, это построить поверх Enterprise Library, которая предоставляет некоторые готовые возможности для работы со счетчиками производительности.Например: обработчик счетчика производительности

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

Кроме того, она позволяет создаватьКроме того, вы можете создать AvergeTimeMeter, который позволяет вам просто сделать это:

private static EnterpriseLibraryPerformanceCounter averageRequestTimeCounter = PerformanceCounterManager.GetEnterpriseLibraryCounter(MadPerformanceCountersListener.AverageRequestTime);
private static EnterpriseLibraryPerformanceCounter averageRequestTimeCounterBase = PerformanceCounterManager.GetEnterpriseLibraryCounter(MadPerformanceCountersListener.AverageRequestTimeBase);

public void DoSomethingWeWantToMonitor()
{
    using (new AverageTimeMeter(averageRequestTimeCounter, averageRequestTimeCounterBase))
    {
        // code here that you want to perf mon
    }
}

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

Для этого вы создадите повторно используемый класс AverageTimeMeter, например:

public sealed class AverageTimeMeter : IDisposable
{
    private EnterpriseLibraryPerformanceCounter averageCounter;
    private EnterpriseLibraryPerformanceCounter baseCounter;
    private Stopwatch stopWatch;
    private string instanceName;

    public AverageTimeMeter(EnterpriseLibraryPerformanceCounter averageCounter, EnterpriseLibraryPerformanceCounter baseCounter, string instanceName = null)
    {
        this.stopWatch = new Stopwatch();
        this.averageCounter = averageCounter;
        this.baseCounter = baseCounter;
        this.instanceName = instanceName;
        this.stopWatch.Start();
    }

    public void Dispose()
    {
        this.stopWatch.Stop();
        if (this.baseCounter != null)
        {
            this.baseCounter.Increment();
        }

        if (this.averageCounter != null)
        {
            if (string.IsNullOrEmpty(this.instanceName))
            {
                this.averageCounter.IncrementBy(this.stopWatch.ElapsedTicks);
            }
            else
            {
                this.averageCounter.SetValueFor(this.instanceName, this.averageCounter.Value + this.stopWatch.ElapsedTicks);
            }
        }
    }

}

Вы должны зарегистрировать свои счетчики производительности (показанные в примерах EntLib), но это должно получитьВы начали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...