|
|
1
70
我还没有看到这种效果——我肯定从未遇到过瓶颈。 这里有一个非常粗略和准备好的基准,显示(无论如何在我的盒子上)代表实际上 更快 比接口:
结果(.NET 3.5;.NET 4.0B2大致相同):
现在我没有特别的信仰,这意味着代表们 真正地 比接口更快…但这让我相当确信它们不是一个数量级的慢。此外,这在委托/接口方法中几乎什么都不做。显然,随着每次调用所做的工作越来越多,调用成本将产生越来越小的差异。 需要注意的一件事是,在只使用单个接口实例的情况下,您不会多次创建新的委托。这个 能够 引起一个问题,因为它会引发垃圾收集等。如果您在循环中使用实例方法作为委托,您会发现在循环外部声明委托变量、创建单个委托实例并重用它更有效。例如:
效率高于:
这可能是你看到的问题吗? |
|
|
2
19
由于clr v 2,委托调用的成本与用于接口方法的虚拟方法调用的成本非常接近。 见 Joel Pobar 的博客。 |
|
|
3
18
我发现完全不可信的是,委托比虚拟方法快得多或慢得多。如果有的话,学员应该以可以忽略的速度进行培训。在较低的层次上,委托通常实现如下(使用C样式表示法,但请原谅任何小的语法错误,因为这只是一个示例):
调用代理的工作方式如下:
翻译成C的类如下:
要调用vritual函数,请执行以下操作:
它们基本上是相同的,只是当使用虚拟函数时,需要经过一个额外的间接层来获取函数指针。然而,这个额外的间接层通常是免费的,因为现代的CPU分支预测器将猜测函数指针的地址,并在查找函数地址的同时推测地执行其目标。我发现(尽管是在D中,而不是在C中)紧密循环中的虚函数调用并不比非内联直接调用慢,前提是对于任何给定的循环运行,它们总是解析为相同的实际函数。 |
|
|
4
5
我做了一些测试(在.NET 3.5中…稍后我将使用.NET 4在家进行检查。 事实是: 将对象作为接口获取然后执行该方法比从方法中获取委托然后调用该委托要快。 考虑到变量已经是正确的类型(接口或委托),简单地调用它可以使委托获胜。 出于某种原因,通过接口方法(可能是通过任何虚拟方法)获取委托要慢得多。 而且,考虑到有些情况下,我们Simple不能预先存储委托(例如,在Dispatches中),这可能解释为什么接口更快。 结果如下: 要获得真正的结果,请在发布模式下编译此文件,然后在Visual Studio外部运行它。
如你所见,直拨电话很快。 在前面存储接口或委托,然后只调用它是非常快的。 但是,获得委托比获得接口要慢。 必须通过接口方法(或虚拟方法,不确定)获取委托的速度确实很慢(将获取对象作为接口的5秒与执行相同操作的近4分钟进行比较)。 生成这些结果的代码如下:
|
|
|
5
1
代理是容器这一事实呢?多播能力不会增加开销吗?当我们讨论这个问题时,如果我们把这个容器方面再推进一点呢?如果d是委托,执行d+=d,或者构建(上下文指针、方法指针)对的任意复杂有向图,没有什么能阻止我们。在哪里可以找到描述调用委托时如何遍历此图的文档? |