C# 为什么不';默认情况下是否自动内联属性?

C# 为什么不';默认情况下是否自动内联属性?,c#,compiler-construction,inline,jit,C#,Compiler Construction,Inline,Jit,由于属性只是隐藏的方法,所以可以理解,它们可能执行的任何逻辑的性能可能会提高性能,也可能不会提高性能——因此,可以理解为什么JIT需要检查方法是否值得内联 但是,自动属性(据我所知)不能有任何逻辑,只能返回或设置基础字段的值。据我所知,编译器和JIT处理自动属性就像处理任何其他方法一样。 (以下所有内容均取决于上述段落是否正确的假设。) 值类型属性显示的行为与变量本身不同,但引用类型属性应该具有与直接访问基础变量完全相同的行为 // Automatic Properties Example pu

由于属性只是隐藏的方法,所以可以理解,它们可能执行的任何逻辑的性能可能会提高性能,也可能不会提高性能——因此,可以理解为什么JIT需要检查方法是否值得内联

但是,自动属性(据我所知)不能有任何逻辑,只能返回或设置基础字段的值。据我所知,编译器和JIT处理自动属性就像处理任何其他方法一样。
(以下所有内容均取决于上述段落是否正确的假设。)

值类型属性显示的行为与变量本身不同,但引用类型属性应该具有与直接访问基础变量完全相同的行为

// Automatic Properties Example
public Object MyObj { get; private set; }
是否有任何情况下,
引用类型的自动属性通过内联显示性能受到影响?
如果没有,是什么阻止编译器或JIT自动内联它们?


注意:我理解性能增益可能是微不足道的,特别是当JIT在使用足够多的时间后很可能会内联它们时——尽管增益可能很小,这样一个看似简单的优化无论如何都会被引入,这似乎是合乎逻辑的。

自动属性就是自动生成的-property get/set方法。因此,IL对他们来说没有什么特别之处。C#编译器本身做得非常好

至于为什么不内联的原因——假设您的类型在一个单独的程序集中,因此您可以自由地更改该程序集的源代码,使其具有极其复杂的属性get/set。结果,当编译器在根据您的类型创建新程序集时第一次看到您的自动属性时,它无法根据get/set代码的复杂性进行推理

正如您在问题中已经指出的——“特别是当JIT可能会将它们内联时”——此属性方法可能会在JIT时内联

但是,自动属性(据我所知)不能有任何 逻辑,只需返回或设置基础字段的值。作为 据我所知,自动属性由编译器和 JIT和其他方法一样

自动属性不能有任何逻辑是一个实现细节,编译不需要任何关于这一事实的专门知识。事实上,正如您所说,自动属性被编译为方法调用


假设自动属性是内联的,并且类和属性是在不同的程序集中定义的。这意味着,如果属性实现发生更改,则必须重新编译应用程序才能看到该更改。这首先会妨碍使用属性,因为属性应该允许您在不必重新编译消费应用程序的情况下更改内部实现。

编辑:JIT编译器的工作方式与您认为的不一样,我想这就是为什么您可能没有完全理解我上面试图传达的内容。我在下面引用了你的评论:


这是另一回事,但据我所知,只有在调用足够多次的情况下,才会检查方法是否具有内联价值。更不用说检查本身就是对性能的打击。(暂时不要考虑性能影响的大小。)

首先,检查大多数(如果不是全部的话)方法,看它们是否可以内联。其次,请记住,方法只有一次JIT,JIT将在这一次中确定是否有在其内部调用的方法将被内联。这可能发生在程序执行任何代码之前。什么使被调用的方法成为内联的一个很好的候选者

x86 JIT编译器(x64和ia64不一定使用相同的优化技术)检查一些事情,以确定方法是否适合内联,而不仅仅是调用它的次数。列出了诸如内联是否会使代码变小、调用站点是否会执行多次(即在循环中)等内容。每个方法都是自己优化的,因此该方法可以内联在一个调用方法中,但不能内联在另一个调用方法中,如循环示例中所示。这些优化启发法仅适用于JIT,C#编译器只是不知道:它正在生成IL,而不是本机代码。他们之间有着巨大的差异;本机代码与IL代码的大小可能会有很大不同

总之,出于性能原因,C#编译器不内联属性


jit编译器内联了最简单的属性,包括自动属性。您可以阅读更多关于JIT如何决定内联方法调用的信息

嗯,C#编译器根本不内联任何方法。我认为这种情况是因为CLR的设计方式。每个组件设计为可在机器之间移动。很多时候,您可以在不必重新编译所有代码的情况下更改.NET程序集的内部行为,它可以只是一个替代品(至少在类型没有更改的情况下)。如果代码是内联的,它会破坏(很好,imo)设计,你会失去光泽

我们先来讨论C++中的内联。(完全公开,我暂时没有用C++全职,所以我可能是含糊的,我的解释生疏,或者完全不正确!我指望我的同事们纠正和责骂我)

<> C++就像告诉编译器,“嘿,我想让你把这个函数内联,因为我认为它会提高性能”。不幸的是,它只是告诉编译器您更喜欢内联的;它并没有告诉它必须这样做

也许在更早的时候,当编译器没有像现在这样优化时,编译器通常会编译内联函数。然而,随着时间的推移,编译器变得越来越智能,c