【发布时间】:2010-10-13 09:43:01
【问题描述】:
C# 是否内联访问属性?我知道内联 JIT 的 32 字节(指令?)限制,但它会内联属性还是只是 pure 方法调用?
【问题讨论】:
标签: c# .net optimization clr
C# 是否内联访问属性?我知道内联 JIT 的 32 字节(指令?)限制,但它会内联属性还是只是 pure 方法调用?
【问题讨论】:
标签: c# .net optimization clr
这取决于 JIT(据我所知,C# 编译器不做任何内联),但我相信 JIT 在大多数情况下会内联琐碎的属性。
请注意,它不会内联派生自 MarshalByRefObject 的类型的成员,其中包括 System.Windows.Forms.Control(通过 System.ComponentModel.Component)。
我还看到double 字段在通过属性访问时效率降低 - 可能是因为这方面存在一些微妙之处(由于寄存器使用等)。
另请注意,64 位和 32 位 JIT 是不同的,包括它们对内联内容的处理。
编辑:我刚刚找到了 David Notario 的 2004 blog entry,其中包含更多信息。然而,那是在 2.0 发布之前 - 我不会惊讶地看到它现在至少 一些 发生了变化。无论如何可能会感兴趣。
编辑:Another question 引用了2008 Vance Morrison blog entry,它提供了更多信息。有趣的东西。
【讨论】:
我最近发布了一个类似的问题:
Why are public fields faster than properties?
我的问题是公共字段比属性快,因为我运行的是 64 位 Vista,并且 JIT 也将我的代码编译为 64 位,而我的属性不是 内联。强制项目为 x86 编译确实内联属性,并且属性和公共字段之间没有速度差异。
因此,C# 32 位 JIT 具有内联属性,而 64 位则没有,任何其他非静态方法也没有。
【讨论】:
我花了一段时间才弄清楚,在 Visual Studio 中,您可以查看托管代码的反汇编,在 JIT 编译它之后。
那么为什么不创建一个具有非常简单的访问器属性的类,在发布模式下运行它,设置一个断点,然后查看反汇编的内容呢?
【讨论】:
属性访问是只是一个纯粹的方法调用。编译器为属性访问和具有类似签名的方法调用发出的 IL 没有区别,这可以回答您的问题。
【讨论】:
specialname标志,并且它们的名称是标准化的。 OTOH,要接受 CLR 特殊处理的方法(如构造函数)标有rtspecialname,因此以不同方式处理访问器将违反 CLI/CLR 标准的精神。