【问题标题】:Does C# inline properties?C# 是否内联属性?
【发布时间】:2010-10-13 09:43:01
【问题描述】:

C# 是否内联访问属性?我知道内联 JIT 的 32 字节(指令?)限制,但它会内联属性还是只是 pure 方法调用?

【问题讨论】:

标签: c# .net optimization clr


【解决方案1】:

这取决于 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,它提供了更多信息。有趣的东西。

【讨论】:

  • 值得注意的是,属性是一个或两个 (get_Name, set_Name) 函数的包装器。所以属性内联是对函数内联的最小扩展。
【解决方案2】:

我最近发布了一个类似的问题:

Why are public fields faster than properties?

我的问题是公共字段比属性快,因为我运行的是 64 位 Vista,并且 JIT 也将我的代码编译为 64 位,而我的属性不是 内联。强制项目为 x86 编译确实内联属性,并且属性和公共字段之间没有速度差异。

因此,C# 32 位 JIT 具有内联属性,而 64 位则没有,任何其他非静态方法也没有。

【讨论】:

    【解决方案3】:

    我花了一段时间才弄清楚,在 Visual Studio 中,您可以查看托管代码的反汇编, JIT 编译它之后。

    那么为什么不创建一个具有非常简单的访问器属性的类,在发布模式下运行它,设置一个断点,然后查看反汇编的内容呢?

    【讨论】:

    • 如果(如您所说)花了您一段时间才弄清楚,您为什么不告诉我们该怎么做?
    • 只需单步或闯入代码并打开反汇编窗口。
    • 如果您在调试器下运行发布模式代码,在调试器下运行它可能会禁用 JIT 优化!相反,您需要在没有调试器的情况下启动它,让它 JIT,然后使用调试器附加到已经运行的进程(然后然后打开反汇编窗口)。
    【解决方案4】:

    属性访问只是一个纯粹的方法调用。编译器为属性访问和具有类似签名的方法调用发出的 IL 没有区别,这可以回答您的问题。

    【讨论】:

    • 虽然我同意一般原则,但在 property 方面的 IL is 有所不同...... JIT 当然可以“知道”所调用的是属性成员,因此它可以根据该信息决定不进行 JIT。不过,这样做会很奇怪,IMO。
    • 是的,访问器方法标有specialname标志,并且它们的名称是标准化的。 OTOH,要接受 CLR 特殊处理的方法(如构造函数)标有rtspecialname,因此以不同方式处理访问器将违反 CLI/CLR 标准的精神。
    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2020-05-16
    • 2010-12-04
    相关资源
    最近更新 更多