C#精确到纳秒级别的计时器类
主要用到了win32里面的 QueryPerformanceCounter和QueryPerformanceFrequency两个函数
文档链接:https://docs.microsoft.com/zh-cn/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
1 class NanoSecondTimer 2 { 3 4 [DllImport("Kernel32.dll")] 5 private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); 6 7 [DllImport("Kernel32.dll")] 8 private static extern bool QueryPerformanceFrequency(out long lpFrequency); 9 10 private long startTime, stopTime; 11 private long freq; 12 public NanoSecondTimer() 13 { 14 startTime = 0; 15 stopTime = 0; 16 if (QueryPerformanceFrequency(out freq) == false) 17 { 18 throw new Win32Exception(); 19 } 20 } 21 22 /// <summary> 23 /// 开始计时 24 /// </summary> 25 public void Start() 26 { 27 Thread.Sleep(0); 28 QueryPerformanceCounter(out startTime); 29 } 30 31 /// <summary> 32 /// 停止计时 33 /// </summary> 34 public void Stop() 35 { 36 QueryPerformanceCounter(out stopTime); 37 } 38 39 /// <summary> 40 /// 返回计时器经过时间(单位:秒) 41 /// </summary> 42 public double Duration 43 { 44 get 45 { 46 return (double)(stopTime - startTime) / (double)freq; 47 } 48 } 49 }
QueryPerformanceFrequency这个函数会检索性能计数器的频率。性能计数器的频率在系统启动时是固定的,并且在所有处理器上都是一致的。因此,只需在应用初始化时查询频率,即可缓存结果。在运行 Windows XP 或更高版本的系统上,该函数将始终成功,因此永远不会返回零。
下面是测试代码:
1 NanoSecondTimer nanoSecondTimer = new NanoSecondTimer(); 2 nanoSecondTimer.Start(); 3 for (int i = 0; i < 100000; i++) 4 { 5 i++; 6 } 7 nanoSecondTimer.Stop(); 8 double time = nanoSecondTimer.Duration;