常用的 Windows API 方法 GetTickCount() 返回系统启动后经过的毫秒数。另一方面,GetTickCount() 函数仅有 1ms 的分辨精度,精度也很不好。
我们要另外寻找一种方法来精确测量时间。
Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度计时。这些方法,比“标准的”毫秒精度的计时方法如 GetTickCount() 之类有高得多的精度。
虽然在 C# 中使用“非托管”的 API 函数会有一定的开销,但比起使用一点都不精确的 GetTickCount() API 函数来说要好得多了。
下面的类实现了 QueryPerformanceCounter() 和 QueryPerformanceFrequency() API 函数功能的封装。
代码封装
- using System;
- using System.Runtime.InteropServices;
- using System.ComponentModel;
- using System.Threading;
-
- namespace Win32
- {
- internal class HighTimer
- {
- [DllImport("Kernel32.dll")]
- private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
-
- [DllImport("Kernel32.dll")]
- private static extern bool QueryPerformanceFrequency(out long lpFrequency);
-
- private long startTime, stopTime;
- private long freq;
-
- // 构造函数
- public HighTimer()
- {
- startTime = 0;
- stopTime = 0;
-
- if (QueryPerformanceFrequency(out freq) == false)
- {
- // 不支持高性能计数器
- throw new Win32Exception();
- }
- }
-
- // 开始计时器
- public void Start()
- {
- // 来让等待线程工作
- Thread.Sleep(0);
- QueryPerformanceCounter(out startTime);
- }
-
- // 停止计时器
- public void Stop()
- {
- QueryPerformanceCounter(out stopTime);
- }
-
- // 返回计时器经过时间(单位:秒)
- public double Duration
- {
- get
- {
- return (double)(stopTime - startTime) / (double)freq;
- }
- }
- }
- }
调用方法
- HighTimer pt = new HighTimer(); // 创建新的 HighTimer 对象
- pt.Start(); // 启动计时器
- Console.WriteLine("Test/n"); // 需要计时的代码
- pt.Stop(); // 停止计时器
- Console.WriteLine("Duration: {0} sec/n", pt.Duration); // 打印需要计时部分代码的用时
参考链接
https://mp.weixin.qq.com/s/xIRvgT8HSB0RKOhWV___zQ
特此记录
anlog
2024年5月28日