System.Diagnostics.Stopwatch类在重复调用时通常速度较慢
本文关键字:常速度 速度 Stopwatch Diagnostics 调用 System | 更新日期: 2023-09-27 18:24:49
我有一个应用程序,它必须以33ms+/-几毫秒的固定间隔传输数据包。
因此,我提出了一个SpinTimer
类,如下所示:
class SpinTimer
{
public void SpinWait(double waitTimeInSeconds)
{
if (waitTimeInSeconds < 0.0)
{
throw new ArgumentOutOfRangeException("waitTimeInSeconds", "Must be >= 0.0");
}
Stopwatch timer = new Stopwatch();
double elapsed = 0.0;
timer.Start();
do
{
elapsed = (double)timer.ElapsedTicks / (double)Stopwatch.Frequency;
} while (elapsed < waitTimeInSeconds);
}
}
但是,在分析代码之后,我发现System.Diagnostics.Stopwatch.GetTimestamp()
调用占用了大部分执行时间。需要注意的是,我负担不起线程睡眠和上下文切换的费用,因为这会导致输出速率出现太多"抖动"。
关于配置文件运行的注意事项:
- 线程优先级设置为
ThreadPriority.Highest
- 进程优先级设置为
ProcessPriorityClass.High
我用C++编写的原始程序使用QueryPerformanceCounter()
和QueryPerformanceFrequency()
函数实现了相同的效果。我应该将这些调用与PInvoke一起使用,而不是与Stopwatch
类一起使用吗?或者,还有其他合适的方法吗?
谢谢!
秒表位于诊断名称空间中。它不应该用于性能级别的计时。
你可能想要一个定时器。
您是否尝试过使用System.Windows.Threading.DispatcherTimer?
我已经用这个创建了几个程序,并且从未经历过任何延迟
经过更多的调试(受Eric Lippert评论的启发),我意识到我上面的代码完全按照要求执行。问题是在更高抽象级别调用代码会导致等待时间过长。
感谢您建议使用System.Windows.Threading.DispatcherTimer
和System.Timers.Timer
(我都投了赞成票);然而,在测试了每一个之后,它们的精度都被限制在大约10毫秒,这对我的目的来说还不够好。但是,我确实发现我上面的"紧密"循环代码精确到大约1微秒,这对于我目前的需求来说已经足够了。
其他人可能会发现另一个有用的资源是这篇关于提高Stopwatch
准确性的CodeProject文章。其主要思想是从根本上减少程序经历上下文切换的可能性,从而在调度队列中浪费时间。