从方法返回的开销

本文关键字:开销 返回 方法 | 更新日期: 2023-09-27 18:37:13

我有一个处理一些查询的方法A()。此方法,从左括号到其返回语句之前,时间为 +/-70 毫秒。其中 50% 来自打开连接,大约 20% 来自实际查询,5-10% 用于某些内存访问,其余的(可能)用于处理连接、命令和读取器。

虽然用于处理连接的这一大块时间已经足够烦人了,但更让我困扰的是,当我从方法 B() 调用 A() 时:

B()
{
    var timer = Stopwatch.Startnew()
    A(); 
    timer.Stop(); // elapsed: +/- 250ms
    Debugger.Break();
}

又增加了 180 毫秒的滞后,我似乎无法弄清楚原因。我已经尝试过使用 A 返回 null,它不会改变任何内容。

唯一的磁盘 I/O 和网络发生在 A 中。我认为从磁盘和网络到本地内存的传输应该发生在 A 中,因此从 B 调用 A 不应该受到此影响,但显然情况并非如此?我在这里遇到的网络延迟是吗?如果是这样,那么为什么当我只是让 B 返回 null 时也会发生这种情况?

我目前没有其他解释...

  • 一切都驻留在同一个程序集中,
  • 在没有附加调试器的情况下进行测量没有任何变化,
  • 返回
  • "null"立即显示 0 毫秒,返回 null 而不是正常的返回值不会改变任何内容(但强制执行这与延迟有某种关系的想法)。

A 大致实现如下,就像任何访问数据库的简单方法一样。这是人为的,但显示了基本思想和流程:

A()
{   
    var totalTimer = Stopwatch.StartNew();
    var stuff = new Stuffholder();
    using(connection)
    {
         using(command)
         {
              using(reader) 
              { 
                  // fill 'stuff' 
              }
         } 
    }
    totalTimer.Stop(); // elapsed: +/- 70ms
    return stuff;
}

有什么想法吗?

从方法返回的开销

您看到的开销是由于实时编译造成的。第一次方法B()称为方法A()尚未本机编译(它在 dll 中部分编译为 IL),因此在编译器将A()编译为机器代码时,您会看到轻微的滞后。

在分析方法调用时,必须大量调用该方法并占用平均时间(如果您愿意,可以丢弃第一次调用,尽管超过足够的调用,编译开销应该变得微不足道)。

由于您在 A() 中具有数据库访问权限,因此您可能会遇到网络名称解析问题,因此您的第一次调用需要更长的时间才能执行。