.NET中的高分辨率计时器
时间:2020-03-06 15:02:03 来源:igfitidea点击:
我想对代码进行一些基本的分析,但是发现Conly中的DateTime.Now的分辨率约为16毫秒。必须有更好的时间保存我尚未发现的构造。
解决方案
System.Diagnostics.StopWatch类非常适合分析。
如果我们不想编写自己的测量功能,则这里是Vance Morrison的Code Timer Blog的链接。
我们可以在Windows中调用高分辨率性能计数器。函数名称是kernel32.dll中的QueryPerformanceCounter。
导入C#的语法:
[DllImport("Kernel32.dll")] private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
Windows调用的语法:
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount );
QueryPerformanceCounter @ MSDN
这是计时操作的代码示例:
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)
编辑:
整洁的是它也可以恢复。
Stopwatch sw = new Stopwatch(); foreach(MyStuff stuff in _listOfMyStuff) { sw.Start(); stuff.DoCoolCalculation(); sw.Stop(); } Console.WriteLine("Total calculation time: {0}", sw.Elapsed);
如果系统上有一个System.Diagnostics.Stopwatch类,它将使用高分辨率计数器。
对于最高分辨率的性能计数器,可以使用基础的win32性能计数器。
添加以下P / Invoke信号:
[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);
并使用以下命令致电给他们:
#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
将所有内容转储到一个简单的类中,我们就可以开始了。示例(假设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()));