Bluebit Software
Bluebit Software Support Forum
 Home          Members     Calendar     Who's On

Welcome Guest ( Login | Register )
        



A High Resolution Performance Timer Expand / Collapse
Message
Posted Monday, May 02, 2005 11:06 AM Post #58
 

Bluebit SupportBluebit SupportBluebit SupportBluebit SupportBluebit SupportBluebit SupportBluebit SupportBluebit Support
We publish here some code for a high resolution performance
timer that can be used to measure the performance of your code
to nanosecond accuracy.

The code is beased on this article http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenethowto09.asp
but it has been modified so that the timer can be started and
stopped many times and its Duration property will return the
cumulative elapsed time that the timer has been running.

Normally you will use the PerformanceTimer class as follows:
  • Create a new instance of the PerformanceTimer class.
  • Call the StartTimer method.
  • Execute any code you need to measure its duration in time.
  • Call the StopTimer method.
  • Read the Duration property to get the cumulative elapsed time the timer has been running.
    You may also read this property while the timer is running.
  • Call the Reset method to set the Duration property to 0.

using System;
using System.Runtime.InteropServices;

namespace Bluebit.Utility
{
    /// <summary>The %PerformanceTimer% class can be used to measure intervals of time.</summary>
    /// <remarks>
    /// <para>Normally you will use the <strong>PerformanceTimer</strong> class is as
    /// follows:</para>
    /// <list type="bullet">
    /// <item>Create a new instance of the %PerformanceTimer% class.</item>
    /// <item>Call the
    /// <a href="Bluebit.Learning~Bluebit.Utility.PerformanceTimer~StartTimer.html">StartTimer</a>
    /// method.</item>
    /// <item>Execute any code you need to measure its duration in time.</item>
    /// <item>Call the
    /// <a href="Bluebit.Learning~Bluebit.Utility.PerformanceTimer~StopTimer.html">StopTimer</a>
    /// method.</item>
    /// <item>Read the
    /// <a href="Bluebit.Learning~Bluebit.Utility.PerformanceTimer~Duration.html">Duration</a>
    /// property to get the cumulative elapsed time the timer has been running. You may
    /// also read this property while the timer is running.</item>
    /// <item>Call the
    /// <a href="Bluebit.Learning~Bluebit.Utility.PerformanceTimer~Reset.html">Reset</a>
    /// method to set the
    /// <a href="Bluebit.Learning~Bluebit.Utility.PerformanceTimer~Duration.html">Duration</a>
    /// property to 0.</item>
    /// </list>
    /// </remarks>
    public class PerformanceTimer
    {
        /////////////////////
        #region PRIVATE FIELDS
        private long _freq; // internal performance-counter frequency, in counts per second
        private long _bias; // the time it takes to execute a StartTimer and a StopTimer command.
        private long _start; // last time the timer was started
        private long _stop; // last time the timer was stopped
        private long _duration; // cumulative elapsed time.
        private bool _running; // current state of the timer.
        #endregion
        /////////////////////
        #region EXTERNAL DECLARATIONS
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceCounter(ref long x);
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceFrequency(ref long x);
        #endregion
        /////////////////////
        #region CONSTRUCTOR
        /// <summary>Creates a new instance of the %PerformanceTimer% class</summary>
        public PerformanceTimer()
        {
            QueryPerformanceFrequency(ref _freq);
            if (_freq == 0)
                throw new ApplicationException("The installed hardware does not support a high-resolution performance counter.");

            // calculate the _bias; the first result maybe inaccurate
            StartTimer();
            StopTimer();
            StartTimer();
            StopTimer();
            _bias = _stop - _start;
            _duration = 0;
        }
        #endregion
        /////////////////////
        #region PUBLIC METHODS
        /// <summary>Starts the timer.</summary>
        public void StartTimer()
        {
            if (!_running)
            {
                _running = true;
                QueryPerformanceCounter(ref _start);
            }
        }

        /// <summary>
        /// Stops the timer.
        /// </summary>
        public void StopTimer()
        {
            if (_running)
            {
                QueryPerformanceCounter(ref _stop);
                long d = _stop - _start - _bias;
                d = (d > 0) ? d : 0;
                _duration += d;
                _running = false;
            }
        }
        /// <summary>
        /// Resets the timer.
        /// </summary>
        /// <remarks>
        /// The %Reset% method sets the %Duration% of the timer to zero. If the timer is
        /// running it is stopped.
        /// </remarks>
        public void Reset()
        {
            if (_running) StopTimer();
            _duration = 0;
        }

        #endregion
        /////////////////////
        #region PUBLIC PROPERTIES
        /// <summary>Gets the cumulative elapsed time the timer has been running.</summary>
        /// <value>
        /// A %System.Double% representing the number of seconds the timer has been
        /// running.
        /// </value>
        public double Duration
        {
            get
            {
                if (_running)
                {
                    QueryPerformanceCounter(ref _stop);
                    long d = _stop - _start - _bias;
                    d = (d > 0) ? d : 0;
                    return (double)(_duration + d) / (double)_freq;
                }

                return (double)_duration / (double)_freq;
            }
        }
        /// <summary>
        /// Gets the current performance-counter frequency, in counts per second.
        /// </summary>
        public long Frequency
        {
            get { return _freq; }
        }

        /// <summary>
        /// Gets the current state of the timer.
        /// </summary>
        /// <value>
        /// <strong>true</strong> if timer is running, <strong>false</strong> if timer is
        /// stopped.
        /// </value>
        /// <remarks>
        /// The %StartTimer% method sets this property to <strong>true</strong> whereas the
        /// %StopTimer% method sets it to <strong>false</strong>
        /// </remarks>
        public bool IsRunning
        {
            get { return _running; }
        }
        #endregion
        /////////////////////
    }
}



Trifon Triantafillidis

Lead Developer

Bluebit Software

« Prev Topic | Next Topic »


Reading This Topic Expand / Collapse
Active Users: 0 (0 guests, 0 members, 0 anonymous members)
No members currently viewing this topic.
Forum Moderators: Trifon

Permissions Expand / Collapse

All times are GMT -5:00, Time now is 4:26am

Powered by InstantForum.NET v4.1.4 © 2012
Execution: 0.297. 10 queries. Compression Disabled.
.NET Matrix Library