High resolution timer in .NET

后端 未结 4 1891
一整个雨季
一整个雨季 2020-12-09 14:57

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

相关标签:
4条回答
  • 2020-12-09 15:28

    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

    0 讨论(0)
  • 2020-12-09 15:41

    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.

    0 讨论(0)
  • 2020-12-09 15:41

    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()));
    
    0 讨论(0)
  • 2020-12-09 15:52

    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.

    0 讨论(0)
提交回复
热议问题