运行时间测量错误

本文关键字:错误 测量 运行时间 | 更新日期: 2023-09-27 18:13:25

在经过时间测量过程中遇到意外行为。

我从Stopwatch开始上课:

for (int i = 0; i < 100; i++)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    Thread.Sleep(200);
    stopwatch.Stop();
    Console.WriteLine(stopwatch.ElapsedMilliseconds);
}

https://dotnetfiddle.net/3hch1R

但事实证明,每隔一段时间,时间就会少于200毫秒。

然后是DateTime.Now的时代,它也显示出一些奇怪的东西:

for (int i = 0; i < 100; i++)
{
    var start = DateTime.Now.Millisecond;
    Thread.Sleep(200);
    var stop = DateTime.Now.Millisecond;
    Console.WriteLine(stop - start);    
}

https://dotnetfiddle.net/2vo2yw

像这样简单的事情经常会返回负面结果。

因此,我的问题是:这两个类出现这种行为的原因是什么?我如何更准确地测量经过的时间(没有负偏差(
有一篇关于秒表的帖子揭示了这个话题,但那里的评论看起来有点矛盾。

第1版:
正如AlexD所发现的,DateTime.Now.Millisecond只是返回毫秒部分,而不是TotalMilliseconds。所以这一点很清楚。

第2版:
根据建议,我决定使用DateTime,它的结果满足了我的精度要求:

for (int i = 0; i < 100; i++)
{
    var start = (int)DateTime.UtcNow.TimeOfDay.TotalMilliseconds;
    Thread.Sleep(200);
    var stop = (int)DateTime.UtcNow.TimeOfDay.TotalMilliseconds;
    Console.WriteLine(stop - start);    
}

或者DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond,如果测量之间的日期变化对您来说是一种情况。

运行时间测量错误

Ad 1:线程。睡眠不是一种非常准确的睡眠方法。。。我建议你结合使用睡眠和忙碌等待:睡眠180毫秒,然后使用忙碌等待,直到达到200毫秒;这将在最后20ms内100%加载CPU(平均CPU负载为10%,这可能是合理的(,但会给您更准确的发布时间。

广告2:使用DateTime.Ticks(http://msdn.microsoft.com/en-us/library/system.datetime.ticks(v=vs.110(.aspx(,返回"自时间开始"以来经过的"ticks"(间隔100ns(数。

但事实证明,每隔一段时间,时间就会少于200毫秒。

我无法复制您的结果(既不能在本地复制,也不能使用指向dotnetfidd.net的链接(,但无论如何CCD_ 5看起来并不准确。请参阅例如Thread.Sleep(TimeSpan(的准确性?。

也许有点偏离主题,但对于WINAPISleep函数MSDN说(强调我的(:

系统时钟以恒定的速率"滴答"作响。如果dwMilliseconds小于系统时钟的分辨率,则线程可以休眠小于指定的时间长度。如果dwMilliseconds大于一个刻度但小于两个刻度,则等待可以介于一个和两个刻度之间的任何位置,依此类推


像这样简单的事情经常会返回负面结果。

DateTime.Now.Millisecond不返回总计毫秒,只返回毫秒分量。