函数调用和C#中的事件之间是否存在性能差异?

时间:2012-12-13 21:17:02

标签: c# events delegates

我会试着澄清我的问题:

我有一个名为Draw的函数(有人(XNA)每秒调用她60次), 我有很多要绘制的对象,所以我有以下代码:     void Draw()     {     obj1.draw();     obj2.draw();     obj3.draw();     ....     }

如果我将创建一个由Draw()引发的事件,并且所有对象都会注册该事件,是否会对性能产生影响?

如果我不清楚我问的是: 通过注册活动来呼叫功能是否与常规呼叫不同?

2 个答案:

答案 0 :(得分:6)

关于性能,我认为Jon Skeet's example非常有说服力,代表们不会给性能增加任何重大开销,甚至可能会改进它。

您需要考虑事件/委托的一个因素是处理侦听事件的取消对象或您的引用计数将无法正确重置,您会发现自己有内存泄漏。避免使用匿名方法,除非您准备存储对它们的引用,以便它们可以在Dispose等上取消连接。

答案 1 :(得分:4)

ildasm显示使用“call method”命令执行函数的直接调用,而使用“callvirt delegatename :: Invoke()”执行调用事件。似乎直接调用应该更快,但让我们考虑什么是Invoke()。 Invoke不是Delegate或MulticastDelegate类的成员。这是编译器生成的特殊方法

.method public hidebysig virtual instance void 
            Invoke(string s) runtime managed
{
}

此方法不包含任何可能看起来很奇怪的实现。但是,如果我们关注“运行时”特定器,魔法就会消失。 “运行时”意味着代码将在运行时生成,而且正如我们所知,它只会发生一次。因此从理论上讲,两者在生产力方面应该是相同的。

至于Jon Skeet的测试,我发起了几次并在代表的帮助下与呼叫交换直接呼叫,并没有得到代表们提高性能的确认。有时代表赢了,有时直接打电话赢了。我认为这是因为GC或.NET内部的其他因素会影响测试,或只是通过Windows切换进程。