【问题标题】:What is the performance expense of string comparisons for INotifyPropertyChanged?INotifyPropertyChanged 的​​字符串比较的性能开销是多少?
【发布时间】:2012-01-03 12:30:34
【问题描述】:

我想知道为什么 MS 决定在 INotifyPropertyChanged 的​​设计中使用字符串?

我最初的担心是在每次更改通知上进行字符串比较会产生大量费用,我想知道是否让我的属性名称保持简短以帮助比较。

但是,鉴于字符串在 .Net 中是不可变的,我想知道运行时是否足够智能,可以通过某种哈希表重用字符串实例,所以比较实际上只是一个参考比较?

有人知道实现细节吗?如果不知道,为什么 MS 会按照他们的方式设计它?

【问题讨论】:

    标签: c# inotifypropertychanged string-comparison


    【解决方案1】:

    如果不是string,你会建议什么?它不能是PropertyInfo,因为并非所有支持此的类型都使用静态类型 - 例如,DataTable 公开了用于绑定目的的自定义属性模型,因为没有许多其他类型(通过任何ICustomTypeDescriptorTypeDescriptionProvider,或ITypedList)。

    即使它PropertyInfo,或者即使它是PropertyDescriptor,你也无法对此进行比较:a:需要很多 获取参考查找的工作量,b:您甚至无法保证(尤其是 PropertyDescriptor)每次查找时都能返回相同的对象。

    也就是说,您最终可能会比较名称(string无论如何

    通过使用string,引发这个事件很便宜,比较也很便宜 - 字符串比较非常快,因为大多数属性名称都很短,而且几乎所有属性都少于 30 个字符。这将比较快得惊人,而且它不是瓶颈。在大多数情况下,“现在它已经改变了要做什么”将比这个字符串比较多花费 很多 时间。

    我面前没有实现,但我希望字符串相等检查基本上是:

    • 相同的参考?返回真
    • 长度不同?返回错误
    • 逐个字符比较;初差时返回 false
    • 返回真

    所以它甚至不应该是一个问题,除非你所有的属性名称都是 a:相同的长度,并且 b:一个非常重要的长度

    基本上:不用担心。

    【讨论】:

      【解决方案2】:

      如果您非常关心实现细节,您可以使用 Telerik 的 JustDecompile,看看他们是如何做到的。 至于为什么 INotifyPropertyChanged 中的字符串,答案是反射。我怀疑他们是否保留了参考来获得实际上微不足道的任务的性能。你说的通知数量是多少?由于 INotifyPropertyChanged 中的字符串比较,普通 WPF/SL 应用程序不会出现性能问题。

      【讨论】:

        【解决方案3】:

        为什么 MS 按他们的方式设计它?

        因为他们需要一种灵活且足够快的方法。当属性发生变化时会发生很多事情,字符串的查找不会成为瓶颈。

        属性注册在一些基础结构中,查找就像字典一样,这意味着 HashCode 将提供有效的访问。字符串都将被保留,但这还不够可靠,无法从引用中确定不相等性。

        保持属性名称简短不会带来任何可衡量的改进,最好使用有意义的名称。

        【讨论】:

          【解决方案4】:

          每当你生成一个新字符串时,它都会在内存中占据自己的空间,无论是否已经存在具有相同内容的字符串。

          另一方面,当您将字符串变量显式分配给另一个变量时,只会复制引用。使用常量是另一种节省内存的方法。

          通过像哈希表这样的机制重用实例需要更大的开销和比较机制,每当创建字符串时都会调用这些机制。在大多数情况下,这可能更多的是性能问题,而不仅仅是存储另外几个字节。

          【讨论】:

          • Interned 的字符串呢?
          • @HarisHasan 引用可以使用String.Intern 显式检索。
          • 我有点困惑Whenever you generate a new string, it will occupy its own space in memory, no matter if a string with the same content already exists. 当我们说字符串文字可能会或可能不会被自动实习时,这是否意味着上面的说法不正确?
          • @HarisHasan 我的陈述非常广泛,绝对不适用于您能想到的每一种情况。我决定让答案保持简单。请随意查看特殊情况的文档。
          【解决方案5】:

          我会考虑消费者——如果你是一个数据绑定的网格,你已经将属性名称作为你感兴趣的列的字符串。还可以考虑引发事件——获取PropertyInfo并不便宜,而对字符串进行硬编码。

          【讨论】:

            【解决方案6】:

            我认为与其他机制(例如绑定)相比,字符串比较根本不昂贵,因此字符串绝对不是瓶颈。

            也就是说,在代码中使用常量字符串(我的意思是 PropertyChanged(this, new PropertyChangedEventArgs("MyProperty")))速度很快,但我个人更喜欢使用反射来动态获取属性的名称:它需要更多的工作,但它大大提高了可维护性并减少了错误数量(最常见的是“我重命名了我的属性,但我忘记更改PropertyChanged 事件的参数”)。

            【讨论】:

              猜你喜欢
              • 2017-09-27
              • 1970-01-01
              • 2011-11-23
              • 2010-10-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-03-07
              相关资源
              最近更新 更多