System.Diagnostics.Stopwatch是否不准确?

Joh*_*per 3 .net c# performance time datetime

我经常使用System.Diagnostics.Stopwatch来测量代码执行的时间.文档说它应该非常准确.我相信测量的时间只能与用于启动和停止秒表的时间不同.

我通过以下代码估计了这个错误有多大:

var sw = new Stopwatch();
sw.Start();
sw.Stop();
Run Code Online (Sandbox Code Playgroud)

它的测量值为:00:00:00.0000090.哇.错误低于10us.

经过多年的努力,我开始对秒表再次产生好奇心.真的那么精确吗?它是否测量挂钟时间?或者究竟是什么测量的定义在哪里?如果进程被IO操作阻止怎么办?它还是那么精确吗?

我再次做了小基准测试:

var sw = new Stopwatch();
var startTime = System.DateTime.Now;
sw.Start();
for (int i = 0; i < 1000; i++) {
    Console.WriteLine(i);
    Console.Error.WriteLine(i);
}
var endTime = System.DateTime.Now;
sw.Stop();
Console.Error.WriteLine(
    @"The application was running {0}, but the stopwatch measured {1}.",
    endTime - startTime,
    sw.Elapsed
);
Run Code Online (Sandbox Code Playgroud)

当我正常启动应用程序时,输出是:

应用程序运行00:00:01.5740900,但秒表测量为00:00:01.5732109.差异几乎是1毫秒.

当我将应用程序的标准输出传递给在读取其输入之前等待一段时间的进程时,我得到以下结果:

应用程序运行00:04:51.2076561,但秒表测量为00:04:51.2012677.

差异超过6毫秒.

怎么了?秒表不准确吗?或者我只是误解了什么是未测量的?

编辑:我知道System.DateTime.Now具有较低的分辨率,但预计差异将以毫秒为单位.

Rah*_*thi 6

我认为你不需要依赖单一测量.您需要多次运行检查(可能是20到50次),然后取平均值.

另请注意,StopWatch是一个基于QueryPerformanceCounter功能的shell .

例如,您可以查看本文:性能测试:使用System.Diagnostics.Stopwatch进行精确的运行时测量


dca*_*tro 6

Stopwatch很好,这endTime - startTime是错的.

DateTime.Now 秒表的分辨率较低.

来自MSDN:

Now属性经常用于衡量性能.但是,由于其分辨率低,因此不适合用作基准测试工具.更好的选择是使用秒表类.