7

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

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

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

又增加了 180 毫秒的延迟,我似乎不知道为什么。我已经尝试过让 A return 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;
}

有任何想法吗?

4

2 回答 2

7

您看到的开销是由于即时编译造成的。第一次B()调用方法时,方法A()没有被本地编译(它在 dll 中部分编译为 IL),所以当编译器编译A()成机器码时,你会看到轻微的延迟。

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

于 2013-10-29T14:40:23.880 回答
0

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

于 2013-10-29T19:28:14.087 回答