【问题标题】:Is there a performance difference between function call and an event in C#?C# 中的函数调用和事件之间是否存在性能差异?
【发布时间】:2012-12-01 20:39:15
【问题描述】:

我会尽量澄清我的问题:

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

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

如果我不清楚我要问的是: 通过注册事件来调用函数是否与常规调用不同?

【问题讨论】:

  • 我无法评论性能,但听起来切换到事件驱动系统会大大提高代码的可维护性,并且肯定是更好的设计。
  • 此外,事件处理程序通常在它们自己的线程上运行。函数调用在同一个线程上运行。由于您在谈论绘图,我认为这将涉及 UI 操作,因此您需要小心。
  • @ryadavilli 我敢肯定,如果您正常触发它们,事件处理程序不会在自己的线程中触发。事件处理程序在当前线程上按顺序执行。

标签: c# events delegates


【解决方案1】:

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 切换进程。

【讨论】:

    【解决方案2】:

    关于性能,我认为Jon Skeet's example 非常有说服力,委托不会增加任何显着的性能开销,甚至可能会提高它。

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

    【讨论】:

      猜你喜欢
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 2014-02-23
      • 1970-01-01
      • 2014-05-17
      相关资源
      最近更新 更多