【问题标题】:Does the C# Compiler optimize nested property calls into inline calls?C# 编译器是否将嵌套属性调用优化为内联调用?
【发布时间】:2013-05-23 15:38:02
【问题描述】:

所以在 .NET 中,我知道获取属性值比获取字段值更昂贵,前提是该属性在 getter 中具有某种逻辑。我的问题有两个方面。考虑以下示例:

foreach(var item in collection)
{
    item.SomeField = StaticClass.PropertyA.PropertyB.PropertyC;
}

所以(希望很明显)StaticClass 是一个静态类,其右侧的所有属性都是某个类的实例。此外,所有属性都是字段的纯粹包装器,因此PropertyA 有一个仅返回一个字段的 getter 和一个分配给该字段的 setter,等等。

通过单步执行可以看出,为了检索值,必须进行三个方法调用(get_PropertyA()get_PropertyB()get_PropertyC())。我的第一个问题是:

编译器是否优化了这个扩展,只评估这三个方法调用一次(即内联它们的主体)?还是每次迭代都会调用三个方法?

我会被引导相信后者是真的。

此外,让我们假设这段特定的代码在整个应用程序中被广泛使用。如果后者为真,那么在进入循环之前将PropertyC 的值存储在局部变量中并在循环中使用该局部变量来尝试优化方法本身是否有意义?

提前致谢。这个问题确实偏向于讨论,但我相信有一个明确的答案。

【问题讨论】:

  • 得墨忒耳的神圣法则,蝙蝠侠!
  • 您是否真的生成了 IL 并查看了编译器的作用?此外,这似乎是一种微优化。
  • 嗯,问题的一部分是a)它实际上是一种优化,b)它是否值得。并且感谢 LoD 的事情,虽然我认为它有点投机(我只提供了实际发生的事情的模棱两可的版本)。
  • 另外,为什么投反对票?我不认为这个问题表明缺乏研究、含糊不清或促进讨论。标题不好,是的。
  • 这是 .NET 编程的伟大神话之一。属性比字段贵。抖动优化了 getter 和 setter 方法,将它们内联,因此最终的机器代码与字段访问完全相同。没有先分析代码就漫无目的地优化代码是浪费时间。

标签: .net optimization properties


【解决方案1】:

.NET 内存模型要求对循环的每次迭代计算一次操作。如果您知道StaticClass.PropertyA.PropertyB.PropertyC 的结果是一个常量值(或至少在该循环中是常量),您应该在循环外声明一个字段来保存它的值。

var value = StaticClass.PropertyA.PropertyB.PropertyC;
foreach (var item in collection)
    item.SomeProperty = value;

【讨论】:

    猜你喜欢
    • 2011-03-18
    • 2019-04-29
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多