System.Diagnostics.Stopwatch是否不准确?

时间:2015-05-31 09:37:43

标签: c# .net performance datetime time

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

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

var sw = new Stopwatch();
sw.Start();
sw.Stop();

测量: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
);

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

  

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

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

  

应用程序正在运行00:04:51.2076561,但秒表的测量值为00:04:51.2012677。

差异超过6毫秒。

发生了什么事?秒表不准确吗?或者我只是误解了什么是什么,什么没有被测量?

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

2 个答案:

答案 0 :(得分:6)

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

另请注意,StopWatch是一个超过QueryPerformanceCounter功能的shell。

您可以查看此文章:Performance Tests: Precise Run Time Measurements with System.Diagnostics.Stopwatch

答案 1 :(得分:6)

Stopwatch没问题,endTime - startTime错了。

DateTime.Now的分辨率低于秒表。

来自MSDN

  

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