运行时间测量错误
本文关键字:错误 测量 运行时间 | 更新日期: 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
不返回总计毫秒,只返回毫秒分量。