如何在c#中捕获准确的执行时间

时间:2015-03-19 10:07:11

标签: c#

我尝试捕获函数的确切执行时间

Stopwatch regularSW = new Stopwatch();
for (int i = 0; i < 10; i++) {
    regularSW.Start();
    //function();
    regularSW.Stop();

    Console.WriteLine("Measured time: " + regularSW.Elapsed);
}

我也试过DateTimeProcess.GetCurrentProcess().TotalProcessorTime 但每次我得到不同的价值。

我如何获得相同的价值?

1 个答案:

答案 0 :(得分:5)

使用StopWatch,您已经使用了最准确的方法。但是你没有在循环中重新启动它。它总是从它结束的值开始。您必须创建新的StopWatch或致电StopWatch.Restart而不是Start

Stopwatch regularSW = new Stopwatch();
for (int i = 0; i < 10; i++) {
    regularSW.Restart();
    //function();
    regularSW.Stop();
    Console.WriteLine("Measured time: " + regularSW.Elapsed);
}

这就是不同价值观的原因。如果你现在仍然得到不同的值,那么原因是方法function确实具有不同的执行时间,这不是那么不可能(例如,如果它是数据库查询)。


由于这个问题似乎主要是理论上的(关于你的评论),如果你想在.NET中测量时间,请考虑以下事项:

  • 在发布模式下编译并运行,任何CPU(在x64计算机上)和优化
  • 勾选是0.0001毫秒,所以不要高估你的结果
  • 它们不同,因为在C#编程运行时,您无法控制系统可能需要在后台执行的其他操作
  • 如果您因为填写本地列表而在方法中声明内存,那么垃圾收集器可能会尝试回收垃圾(内存)
  • C#代码是及时编译的。因此,由于分析环路调用的代码的抖动成本,第一次通过循环可能比后续每个时间贵几百或几千倍。如果您打算测量循环的“温暖”成本,那么您需要在开始计时之前运行循环一次。如果您打算测量包括jit时间在内的平均成本,那么您需要确定合理数量的试验次数,以便平均值正常运行
  • 您正在多线程,多处理器环境中运行代码,其中线程可以随意切换,并且线程量(操作系统将给予另一个线程直到您的机会再次运行的时间)是大约16毫秒。 16毫秒是大约五千万个处理器周期。如果线程切换发生在您尝试测量的数百万个处理器周期之一内,那么提供精确的亚毫秒操作时序可能非常困难。考虑到这一点。

最后两点是从this answer of Eric Lippert复制的(值得一读)。

相关问题