【问题标题】:Is System.Diagnostics.Stopwatch inaccurate?System.Diagnostics.Stopwatch 不准确吗?
【发布时间】:2015-08-13 21:01:47
【问题描述】:

我经常使用 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。

相差6ms以上。

发生了什么?秒表不准确吗?还是我只是误解了什么是衡量的,什么不是衡量的?

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

【问题讨论】:

    标签: c# .net performance datetime time


    【解决方案1】:

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

    还要注意,StopWatch 是 QueryPerformanceCounter 功能的外壳。

    您可以例如查看这篇文章:Performance Tests: Precise Run Time Measurements with System.Diagnostics.Stopwatch

    【讨论】:

      【解决方案2】:

      Stopwatch 没问题,endTime - startTime 错了。

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

      来自MSDN

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

      【讨论】:

      • 由于操作系统和进程不是实时的,这种精确的测量是否可以被认真对待?我的意思是,当执行经常被中断时,测量执行时间的意义何在?
      • @SriramSakthivel 我已经修改了我的答案
      • @Dusan - 在现代硬件和操作系统上,绝对!在优秀的 MSDN 文章中阅读更多内容:Acquiring high-resolution time stamps
      猜你喜欢
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 2020-02-29
      • 1970-01-01
      • 2021-05-27
      相关资源
      最近更新 更多