[英]Unsubscribing from events - performance hit?
请考虑以下代码(来自性能报告):
这是属性通知侦听器组件的一部分。 OnItemPropertyChanged
方法是一个带有PropertyChangedEventHandler
签名的私有实例绑定方法。 该方法被调用大约100.000次并且导致应用程序中的显着延迟。
是否存在与(un)订阅事件相关的性能考虑因素? 有没有解释为什么会导致这样的性能损失?
首先要注意的是:
notificationItem.PropertyChanged -= OnItemPropertyChanged;
为此目的实际分配了一个新的代表。 它还意味着等价测试不能在身份等同性上短路 - 它必须执行方法/目标等价(即不同的委托实例,但是相同的目标/方法,因此被认为是代表组合的等价物)。
我会先尝试将使用一个单一的委托实例,即
void OnItemPropertyChanged(object sender, PropertyChangedEventArgs args) {...}
private readonly PropertyChangedEventHandler sharedHandler;
public YourType() { // constructor
sharedHandler = OnItemPropertyChanged;
}
然后当您订阅时,而不是:
notificationItem.PropertyChanged += OnItemPropertyChanged;
要么
notificationItem.PropertyChanged -= OnItemPropertyChanged;
改为使用:
notificationItem.PropertyChanged += sharedHandler;
要么
notificationItem.PropertyChanged -= sharedHandler;
值得一试,至少。
注意94.2%
与相对执行时间有关。 因此取消订阅占用了Disable(..)
方法总执行时间的94.2%
。 考虑到其他代码raw是cast
和null
检查,这是正常的。
真正的问题,imo(即使有关性能的任何事情与具体的执行上下文严格相关)是这种方法被称为100.000
次。
关于许多评论提出的设计缺陷:我们强烈建议用户不要将带有100k对象的对象图放入用户界面; 这是持续改进过程的一部分,希望将来能够得到解决。
传递给unsubscription运算符的sharedHandler
和Method
引用之间没有显着差异。
使用弱事件管理器类可以消除性能损失; 无论有没有创建像Marc Gravell这样的代表建议。 也许这与此类有关,它以不同的方式创建自己的事件侦听器,而不是使用其参数中提供的那个。 我已经查看了源代码但无法找到解释为什么这个模式看起来似乎运行得很快(因为仍然调用了+=
和-=
运算符)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.