【问题标题】:Events in C#C# 中的事件
【发布时间】:2008-10-02 12:56:33
【问题描述】:

事件到底慢了多少?我编写了一个流式 XML 解析器(可以处理开放式和不完整的文档),并且通过删除事件并改用接口,我获得了显着的速度提升。

还有其他人有什么战争故事吗?

(这里不要打开蠕虫的GC罐,我们都知道它坏了:))

【问题讨论】:

  • 比什么慢? GC 什么时候坏了?
  • 严重的是,你刚刚自己开了一罐蠕虫。
  • @bob-dizzle @david-humpohl 我们在通用基类上实现了 IDisposable 并明确清除了事件。内存使用量下降了,哦,只有大约 900mb(一半)。检查您的来源。 bit.ly/ZNw9E。我的大脑可能坏了,但我的大脑没有在客户的机器上运行,明白吗?

标签: c# .net performance events


【解决方案1】:

事件触发是委托调用,即a bit slower than virtual calls


(来源:microsoft.com

但是处理订阅者/发布者/观察者/可观察场景的接口比使用事件更痛苦。

【讨论】:

  • 根据您的图表,事件是委托调用。
  • 委托调用是委托调用。以下两个调用产生相同的 IL: myEventHandler(this, EventArgs.Empty); myEventHandler.Invoke(this, EventArgs.Empty);
【解决方案2】:

事件实际上只是代表。据我回忆,它们在 2.0 CLR 中变得更快了。我很惊讶用接口替换事件使您的代码明显更快 - 根据我的经验,它们非常快,如果您正在处理 XML,我不会期望事件调用成为瓶颈。

您的代码是否经常订阅和取消订阅事件?您是否知道解析特定文档时进行的事件调用次数?

【讨论】:

  • “我很惊讶事件让你的代码明显更快”——你的意思是更慢;)
  • 不,每个客户端有一个 XML 解析器。每个文档的 XML 调用范围可以达到数百万,它是一种 IM 协议。
  • 我的意思是“很惊讶远离事件让你的代码明显更快” - 编辑,谢谢:)
  • 关于瓶颈,你是完全正确的。这是我对 XMPP 的抱怨之一,但我编写了一个二进制 XML 解决方案(它类似于 EXI,但真正关注的是速度而不是大小),它可以由客户端在任何时候启动(如 STARTTLS)。
【解决方案3】:

事件肯定比直接的函数调用慢,我不能告诉你到底慢了多少,但很明显。您也可以将代表传递给“中间”立场。 .NET 事件系统使用委托,但直接通过委托调用方法与整个事件系统相比仍然更快。

【讨论】:

  • 真的很奇怪。我的意思是,如果它在委托上运行,为什么它比使用委托本身要慢。
【解决方案4】:

与虚拟方法调用相比,委托的开销较小,因为它们是方法列表,因此理论上可以调用多个处理程序。

【讨论】:

  • 我不确定,我使用界面的原因是因为只有一个订阅者。这意味着该列表将包含一项。我想知道发生了什么,也许我应该打开 Reflector 并查看差异。
  • 即使列表只有一项,迭代它而不是直接调用方法(即使是虚拟方法)也必然会稍微慢一些。
【解决方案5】:

如果调用中不涉及反射,那么我认为开销可以忽略不计。假设当然可能是错误的。您是否有一个微型基准来证明这一点?

【讨论】:

  • 我可以试着一起鞭打一个。正如我(认为)我所说的那样,速度的提高是观察性的(但在那方面很重要)。
猜你喜欢
  • 2010-10-24
  • 2011-07-28
  • 2011-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多