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()调用占用了大部分执行时间。需要注意的是,我负担不起线程睡眠和上下文切换的费用,因为这会导致输出速率出现太多"抖动"。

关于配置文件运行的注意事项:

  1. 线程优先级设置为ThreadPriority.Highest
  2. 进程优先级设置为ProcessPriorityClass.High

我用C++编写的原始程序使用QueryPerformanceCounter()QueryPerformanceFrequency()函数实现了相同的效果。我应该将这些调用与PInvoke一起使用,而不是与Stopwatch类一起使用吗?或者,还有其他合适的方法吗?

谢谢!

System.Diagnostics.Stopwatch类在重复调用时通常速度较慢

秒表位于诊断名称空间中。它不应该用于性能级别的计时。

你可能想要一个定时器。

您是否尝试过使用System.Windows.Threading.DispatcherTimer?

我已经用这个创建了几个程序,并且从未经历过任何延迟

经过更多的调试(受Eric Lippert评论的启发),我意识到我上面的代码完全按照要求执行。问题是在更高抽象级别调用代码会导致等待时间过长。

感谢您建议使用System.Windows.Threading.DispatcherTimerSystem.Timers.Timer(我都投了赞成票);然而,在测试了每一个之后,它们的精度都被限制在大约10毫秒,这对我的目的来说还不够好。但是,我确实发现我上面的"紧密"循环代码精确到大约1微秒,这对于我目前的需求来说已经足够了。

其他人可能会发现另一个有用的资源是这篇关于提高Stopwatch准确性的CodeProject文章。其主要思想是从根本上减少程序经历上下文切换的可能性,从而在调度队列中浪费时间。