Sponsored Ad

Thursday, October 22, 2009

C# Performance

In some applications of the methods of accurate measurement of time are very important. Frequent use of Windows API method GetTickCount () retrieves the number of milliseconds that have elapsed since the inception of the system, but the GetTickCount () function only archive of the resolutions of 1 ms and at the other end are very inaccurate.

High resolution timing is supported in Win32 by the QueryPerformanceCounter() & QueryPerformanceFrequency() API methods. This timer functions has much better resolution than the "standard" millisecond-based timer calls, like the GetTickCount() system. On the other side there is also a tiny bit overhead when calling this "unmanaged" API methods from C#, but it is better than using the very imprecise GetTickCount() API function.

The first call, QueryPerformanceCounter (), check out the real value of high-resolution timer performance at any time. The second function, QueryPerformanceFrequency (), return the number of counts per second that the high-resolution counter performs. To retrieve the elapsed time of a section of code that has to get the real value of high-resolution performance counter immediately before and immediately after the section of code that is timed. The difference between these values indicates the charges that elapsed while the code being executed. The elapsed time can be computed then, by dividing this difference by the number of counts per second that the high-resolution counter performs (the frequency of the high-resolution timer).

duration = (stop - start) / frequency

The following class implements the functionality of the QueryPerformanceCounter () and QueryPerformanceFrequency () methods of the API.

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;

namespace Win32
{
    internal class HiPerfTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(
            out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(
            out long lpFrequency);

        private long startTime, stopTime;
        private long freq;

        // Constructor

        public HiPerfTimer()
        {
            startTime = 0;
            stopTime  = 0;

            if (QueryPerformanceFrequency(out freq) == false)
            {
                // high-performance counter not supported

                throw new Win32Exception();
            }
        }

        // Start the timer

        public void Start()
        {
            // lets do the waiting threads there work

            Thread.Sleep(0);

            QueryPerformanceCounter(out startTime);
        }

        // Stop the timer

        public void Stop()
        {
            QueryPerformanceCounter(out stopTime);
        }

        // Returns the duration of the timer (in seconds)

        public double Duration
        {
            get
            {
                return (double)(stopTime - startTime) / (double) freq;
            }
        }
    }
}

0 comments:

Post a Comment

Sponsored Ad

Website Update

Followers