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

Ome*_*ega 2 c#

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

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

    Console.WriteLine("Measured time: " + regularSW.Elapsed);
}
Run Code Online (Sandbox Code Playgroud)

我也试图与DateTimeProcess.GetCurrentProcess().TotalProcessorTime 但每次我得到不同的值.

我怎么能得到相同的价值?

Tim*_*ter 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);
}
Run Code Online (Sandbox Code Playgroud)

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


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

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

最后两点是从Eric Lippert的回答中复制的(值得一读).