gpt4 book ai didi

c# - 这到底有多慢? INotifyPropertyChanged 使用 StackTrace

转载 作者:太空狗 更新时间:2023-10-29 22:28:41 24 4
gpt4 key购买 nike

今天,我发现了一种实现 INotifyPropertyChanged 接口(interface)的有趣方法。我们可以简单地调用 RaisePropertyChanged(); 而不是传递属性更改的字符串名称或 lambda 表达式。从 setter 中,标记调用是无参数的。这是 RaisePropertyChanged() 方法中的代码:

public virtual void RaisePropertyChanged()
{
var frames = new System.Diagnostics.StackTrace();
for (var i = 0; i < frames.FrameCount; i++)
{
var frame = frames.GetFrame(i).GetMethod() as MethodInfo;
if (frame != null)
if (frame.IsSpecialName && frame.Name.StartsWith("set_"))
{
RaisePropertyChanged(frame.Name.Substring(4));
return;
}
}
throw new InvalidOperationException("NotifyPropertyChanged() can only by invoked within a property setter.");
}

这是一个将通知其家属其更改的属性:

public string MyProperty
{
get { return _myField; }
set
{
_myField= value;
RaisePropertyChanged();
}
}

虽然我觉得这种方法很有趣,但我认为如果属性经常更改......或者如果我们应用程序中的每个属性都使用这种方法来通知其更改,性能损失可能会很严重。

我想听听你的意见。 (不再有 community-wiki 复选框?)这种方法是否非常效率低下?

来源:Article where this approach is presented

最佳答案

我刚刚使用 this code 对其进行了测试. (请注意,我使用 limitation pointed out in Wim Coenen's answer 属性绕过了 MethodImpl。我怀疑这是否是万无一失的解决方法。)

结果:

Raised event using reflection 1000 times in 25.5334 ms.Raised event WITHOUT reflection 1000 times in 0.01 ms.

因此您可以看到,涉及堆栈跟踪的解决方案的成本是“正常”解决方案的大约 2,500 倍

无论如何,这是成比例的答案。我个人不喜欢这个想法(尽管它可能很聪明),其原因远远超出了性能问题;但是,显然,这是您的决定。


编辑:作为记录,I felt compelled to write a blog post about this — 特别是,尽管性能受到影响,但一些开发人员仍会倾向于使用这样的方法。

无论您是否同意我对这个问题的看法(我意识到性能影响在绝对方面很小),我觉得真正的致命打击这个想法是,为了使它更加健壮,有必要使用 MethodImpl 属性装饰您打算从中调用 RaisePropertyChanged 的每个属性 setter ,传递 MethodImplOptions.NoInlining... 就在那里,抵消了您通过其他方式获得的任何打字节省。

所以你在开发时间上留下了净损失(无论你花了多少秒来输入整个 MethodImpl 属性部分),加上性能惩罚。如果你问我,几乎没有理由走这条路。

关于c# - 这到底有多慢? INotifyPropertyChanged 使用 StackTrace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4520570/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com