воскресенье, 24 октября 2010 г.

Perfomance Counter. Счетчик производительности

Когда мы хотим измерить производительность кода, нас интересует время, потраченое на его выполнение. Для этого можно "запомнить" время ДО, и время ПОСЛЕ, вычислить разницу и анализировать результат. В этом случае считается, что процессор все время будет выполнять только этот код. Но на практике может получится так, что во время выполения поток дойдет до середины, процессор переключится на другие потоки, обойдет их, и через некоторое время вернется к нашему. Естественно измерения в этом случае некорректны.

С учетом вышеизложенного, для точных расчетов я использую следующий класс (сперто где-то с просторов интернета):

  class PerfCounter
  {
    private static TimeSpan spStartKernelTime;
    private static TimeSpan spStartUserTime;
    private static ProcessThread procThread;
    private static Int32 idCurrentThread;

    [DllImport("kernel32.Dll", SetLastError = true)]
    public static extern UInt32 GetCurrentThreadId();
    public static bool StartCountOnThread()
    {
      idCurrentThread = (Int32)GetCurrentThreadId();
      try
      {
        foreach (ProcessThread prThread in Process.GetCurrentProcess().Threads)
        {
          if (prThread.Id == idCurrentThread)
          {
            procThread = prThread;
            spStartKernelTime = prThread.TotalProcessorTime;
            spStartUserTime = prThread.UserProcessorTime;
            return true;
          }
        }
      }
      catch (System.Exception e)
      {
        System.Console.WriteLine(e.Message);
        //System.Windows.Forms.MessageBox.Show(e.Message);
        return false;
      }
      return false;
    }

    public static TimeSpan FinishCountOnThread()
    {
      try
      {
        foreach (ProcessThread prThread in Process.GetCurrentProcess().Threads)
        {
          if (prThread.Id == idCurrentThread)
          {
            return prThread.TotalProcessorTime +
             prThread.UserProcessorTime -
             spStartKernelTime - spStartUserTime;
          }
        }
      }
      catch (System.Exception e)
      {
        //System.Windows.Forms.MessageBox.Show(e.Message);
        System.Console.WriteLine(e.Message);
        return TimeSpan.Zero;
      }
      return TimeSpan.Zero; ;

    }
  }


* This source code was highlighted with Source Code Highlighter.

Комментариев нет: