从方法返回的开销
本文关键字:开销 返回 方法 | 更新日期: 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() 中具有数据库访问权限,因此您可能会遇到网络名称解析问题,因此您的第一次调用需要更长的时间才能执行。