C# 字段与属性的实际性能

C# 字段与属性的实际性能,c#,reflection,reflection.emit,C#,Reflection,Reflection.emit,我正在做一些构建后CIL编织,将CIL添加到程序集中的所有方法(换句话说,大量方法)。每个方法都检查特定值是否为null。示例(CIL代码的C#d版本): 将MyType.Something作为属性与字段对性能有何影响?我知道我读到过C#编译器执行特殊的优化,在这种情况下应该不会对性能产生影响……但是如果是直接CIL代码(没有C#编译器)。。。?或者是JIT编译器允许这些优化(因此直接CIL代码仍然有好处) 对静态属性的访问器发出操作码.Call的性能会比Ldsfld差吗(请记住,由于程序集中的

我正在做一些构建后CIL编织,将CIL添加到程序集中的所有方法(换句话说,大量方法)。每个方法都检查特定值是否为null。示例(CIL代码的C#d版本):

将MyType.Something作为属性与字段对性能有何影响?我知道我读到过C#编译器执行特殊的优化,在这种情况下应该不会对性能产生影响……但是如果是直接CIL代码(没有C#编译器)。。。?或者是JIT编译器允许这些优化(因此直接CIL代码仍然有好处)

对静态属性的访问器发出操作码.Call的性能会比Ldsfld差吗(请记住,由于程序集中的每个方法都是编织的,因此这会跨越成千上万的调用)

谢谢。

C#编译器不会对此进行优化,不会-但据我所知,JIT编译器通常可以内联琐碎(和非虚拟)属性


但与所有性能问题一样:如果有疑问,请进行测试

在为SlimDX开发数学库时,我们发现,在.NET 3.5 SP1之前的框架上,为数学类型的成员使用字段(如矢量3的X、Y、Z)会比属性带来不成比例的性能提升。换句话说,对于大量访问属性的小型数学函数,差异是显而易见的

自.NET3.5SP1以来,这一点得到了改进(请参阅)。虽然我相信在此之前的JIT仍然会内联小方法(毕竟属性只是方法),但在早期的框架中存在一个缺陷,它阻止内联采用或返回值类型的方法


请注意,当存在差异时,差异仍然很小。除了性能最关键的情况外,我仍然会选择在所有情况下使用属性

这两个方向的影响都很小。如果您的属性如下所示:

public static SomeType PropertyName
{
    get {return MyType.propertyName;}
    set {MyType.propertyName = value;}
}
确实应该有一个很小的区别。Jit编译器应该将
调用
MyType.set_属性
内联到字段加载中,但即使由于错误而无法实现。我个人犯了一个谨慎的错误,坚持使用属性setter和getter,因为方法体可能会发生变化,因此原始字段访问/变异可能不够


如果要测试,可以强制发出的方法使用关闭内联或优化的
MethodImpl
。然后比较差异,我真的怀疑它是否有意义

你能解释一下你为什么决定实现它吗?我不知道如何在不受“观察者”影响的情况下进行测试,所以我希望有人能马上知道。@JeffN825:我认为如果你能在现实世界的代码中应用测试,而不能观察到任何差异,那么这就足以证明任何差异都是微不足道的:)好的,谢谢。我们使用的是3.5SP1。好奇的是,既然代码是CIL,并且只在构建后可见,那么您仍然使用属性的理由是什么?在您的情况下,我不知道我会使用属性。通常,从库设计和维护的角度来看,rational behind属性是健壮的,但这似乎不适用于这里。
public static SomeType PropertyName
{
    get {return MyType.propertyName;}
    set {MyType.propertyName = value;}
}