views:

1269

answers:

4

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 that I haven't yet found.

+13  A: 

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.

MagicKat
Yup, that one counts ticks on the high resolution clock (if present)... Exactly what I need.
Mats Fredriksson
A: 

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

ChronoPositron
+14  A: 

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 Stopwatch class will use a high-resolution counter if one is available on your system.

quickcel
+3  A: 

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()));
Wolfwyrd
The Stopwatch class does this for you as of .NET 2.0.
Kent Boogaart