【问题标题】:Is there a performance difference between properties vs. backing fields in read/write operations?读/写操作中的属性与支持字段之间是否存在性能差异?
【发布时间】:2011-03-11 04:13:06
【问题描述】:

当在一个类中处理它自己的字段和属性时,我通常只在它执行某些功能时使用该属性(例如限制值或验证或其他)。否则我更喜欢直接读/写支持字段。

我不知何故在脑海中想到,这将是一种更普遍的执行方式,但我突然想到,我真的没有任何证据支持这个想法。

除了惯例或口味之外,一种方法和另一种方法之间是否存在实际的性能因素?

【问题讨论】:

  • 这个问题是在这个问题几个月后提出的;如果有的话,它就是重复的。
  • 我注意到了,但后来我觉得这个问题的措辞更好,得到了更多的关注。在这种情况下,共识是it is ok close the older question
  • 本着这条规则的精神,我投票决定关闭。我确实认为这两个帖子中有用信息的总和比任何一个都多。

标签: .net performance properties backing-field


【解决方案1】:

如果属性是直接获取/设置它的编译器 - 换句话说,编译器将使用属性或字段直接转换为相同的东西 - 所以没有性能差异。

但是,get/sets 可以包含他们想要的任何逻辑,因此可能会很昂贵 - 但是,指南通常建议保持轻便。

属性有一些好处,即使它们只是 get/set 封面:

  • 数据绑定只能看到属性,不能看到字段。
  • 它符合封装的概念。
  • 您可以强制执行只读或只写语义。
  • 您可以将属性单独应用于基础字段(在序列化场景中很有用)。

顺便说一句,尽管回顾这些东西的微小性能特征很有趣 - 在生产代码中应用这种类型的优化(好吧,在这种情况下没有优化)可能 打着过早优化的旗号。

【讨论】:

    【解决方案2】:

    性能应该没有差异。如果你用Reflector看代码的反汇编,它会以最简单的方式自动为你创建backing field。它实际上只是您的编译器为您提供的让生活更轻松的语法糖。

    【讨论】:

      【解决方案3】:

      这真的取决于。从技术上讲,它可能会更慢,但即使在那些情况下,它也几乎是不可察觉的。以下是来自here 的方法内联工作原理。

      • 大于 32 字节 IL 的方法将不会被内联。
      • 虚拟函数没有内联。
      • 具有复杂流控制的方法不会被内联。复杂流控制是除 if/then/else 之外的任何流控制;在这种情况下,switch 或 while。
      • 包含异常处理块的方法不会被内联,但引发异常的方法仍然是内联的候选方法。
      • 如果方法的任何形式参数是结构,则不会内联该方法。

      由于 C# 编译器从属性声明中创建了单独的 getter 和 setter 方法,因此它们显然会相互独立地处理。根据上面的规则,我想说大多数时候属性访问器都是内联的。我认为关于方法必须是非虚拟的规则将是经常发生的不平凡的阻碍之一。

      【讨论】:

      • 将结构作为参数的方法未内联是一个错误,已在 .NET 3.5 SP1 for x86 中修复。而且我相当确定大于 32 字节的方法仍然是内联的候选者,只是不太可能。我认为它使用评分系统来确定一个方法是否被内联,大型方法可能会被扣分,但如果这被积极因素抵消,它可能仍然是内联的。
      • @JulianR:好点。我复制的那篇文章很旧,所以我很确定细节已经改变了一些。
      【解决方案4】:

      如果类或结构公开了结构类型的可变字段,则可以访问该结构的各个字段而无需复制整个内容。相比之下,如果它公开了一个属性(可变或不可变)或“只读”字段,那么访问结构的任何部分都会导致系统复制整个结构,然后访问该副本。此外,消费者代码可以方便有效地修改暴露的结构字段的字段,而无需任何多余的复制操作。相比之下,如果一个结构作为一个属性公开,修改它的任何部分都需要消费者将它复制到一个临时变量,进行更改,然后将其存储回来,一系列步骤可能会导致整个结构被复制四次(读取时供应商和消费者各一次,写入时各一次)。

      【讨论】:

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