从函数内部看到的时间比从调用代码看到的时间要低得多

本文关键字:时间 调用 内部 函数 代码 | 更新日期: 2023-09-27 18:14:00

我有一个时间测量的问题,这真的困扰着我。我正在执行下面的代码(在c#中):

Stopwatch sw = Stopwatch.StartNew();
Foo(args);
sw.Stop();
//log time
public void Foo(var args)
{
    Stopwatch sw = Stopwatch.StartNew();
    //do stuff
    sw.Stop();
    //log time
}

结果是两个时间之间的很大差异,我的代码给了我:函数内部15535毫秒,外部15668毫秒…133ms对我来说似乎很多函数调用(即使有我给我的10个参数),或者是秒表精度(应该是超级精确的)。

你如何解释这种时间上的差异?

注1:同样的事情发生在几个连续的呼叫中:我得到133,81,72,75,75毫秒的差异对于5个呼叫

注2:我的函数的实际参数是:

  • 6类对象
  • 一个struct数组(数组作为引用传递,对吗?)
  • 2 ref =
  • 1输出字节[]
  • 1 out class
  • 1 out结构体(<25个字节)

更新:在Release中,第一次调用的差异甚至更大(在Release中JIT编译是否更昂贵,这可以解释吗?),接下来的步骤有相同的开销(~75毫秒)我尝试在外部初始化秒表,传递一个作为参数并在函数外部记录,差异仍然存在。

我还忘记了我给了一些属性作为必须第一次构造的参数,所以第一次调用的50ms差异可能是由属性初始化和JIT编译来解释的。

从函数内部看到的时间比从调用代码看到的时间要低得多

我的错,这是一个属性调用一个属性做一些磁盘读访问。我以为这是一个简单的成员,没有深入。我将调用从函数调用中取出,时间现在几乎相同(0-1毫秒,我猜是日志记录)

寓意是:属性不应该有副作用。如果你创建的属性没有做什么明显的事情,写一个函数来代替,或者至少在属性的文档中警告下一个开发人员你在做什么!

这个教训的寓意是:如果有什么东西看起来可疑,一定要深入查看调用树!