I\'d like to do some basic profiling of my code, but found that the DateTime.Now in C# only have a resolution of about 16 ms. There must be better time keeping constructs th
You could call down to the high-resolution performance counter in Windows. The function name is QueryPerformanceCounter in kernel32.dll.
Syntax for importing into C#:
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
Syntax for Windows call:
BOOL QueryPerformanceCounter(
LARGE_INTEGER *lpPerformanceCount
);
QueryPerformanceCounter @ MSDN
The System.Diagnostics.StopWatch class is awesome for profiling.
Here is a link to Vance Morrison's Code Timer Blog if you don't want to write your own measurement functions.
For highest resolution performance counters you can use the underlying win32 performance counters.
Add the following P/Invoke sigs:
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public static extern bool QueryPerformanceCounter(out long perfcount);
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public static extern bool QueryPerformanceFrequency(out long freq);
And call them using:
#region Query Performance Counter
/// <summary>
/// Gets the current 'Ticks' on the performance counter
/// </summary>
/// <returns>Long indicating the number of ticks on the performance counter</returns>
public static long QueryPerformanceCounter()
{
long perfcount;
QueryPerformanceCounter(out perfcount);
return perfcount;
}
#endregion
#region Query Performance Frequency
/// <summary>
/// Gets the number of performance counter ticks that occur every second
/// </summary>
/// <returns>The number of performance counter ticks that occur every second</returns>
public static long QueryPerformanceFrequency()
{
long freq;
QueryPerformanceFrequency(out freq);
return freq;
}
#endregion
Dump it all into a simple class and you're ready to go. Example (assuming a class name of PerformanceCounters):
long startCount = PerformanceCounter.QueryPerformanceCounter();
// DoStuff();
long stopCount = PerformanceCounter.QueryPerformanceCounter();
long elapsedCount = stopCount - startCount;
double elapsedSeconds = (double)elapsedCount / PerformanceCounter.QueryPerformanceFrequency();
MessageBox.Show(String.Format("Took {0} Seconds", Math.Round(elapsedSeconds, 6).ToString()));
Here is a sample bit of code to time an operation:
Dim sw As New Stopwatch()
sw.Start()
//Insert Code To Time
sw.Stop()
Dim ms As Long = sw.ElapsedMilliseconds
Console.WriteLine("Total Seconds Elapsed: " & ms / 1000)
EDIT:
And the neat thing is that it can resume as well.
Stopwatch sw = new Stopwatch();
foreach(MyStuff stuff in _listOfMyStuff)
{
sw.Start();
stuff.DoCoolCalculation();
sw.Stop();
}
Console.WriteLine("Total calculation time: {0}", sw.Elapsed);
The System.Diagnostics.Stopwatch class will use a high-resolution counter if one is available on your system.