字段与属性的实际性能

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

// CIL woven region start if (MyType.Something == null) { // ... some new stuff } // CIL woven region end 

将MyType.Something作为属性与字段的性能影响是什么? 我知道我已经读过C#编译器执行特殊优化,在这种情况下应该没有性能影响…但是在直接CIL代码(没有C#编译器)的情况下……? 或者它是允许这些优化的JIT编译器(因此直接CIL代码仍然有益)?

为静态属性的访问器发出OpCode.Call的性能是否比Ldsfld差(请注意,由于程序集中的每个方法都是编织的,所以这是成千上万次的调用)?

谢谢。

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

自从.NET 3.5 SP1以来,这已得到改进(参见JIT inling )。 虽然我认为之前的JIT仍然会内联小方法(属性毕竟只是方法),但早期框架中存在一个错误,它阻止了内联或返回值类型的方法。

请注意,差异在那里仍然很小。 除了性能最关键的案例之外,我仍然会选择使用属性。

C#编译器不会对此进行优化,不会 – 但就我所知,JIT编译器通常可以内联简单(和非虚拟)属性。

与所有性能问题一样:如有疑问,请测试!

在任何一个方向上效果都很小。 如果您的属性如下所示::

 public static SomeType PropertyName { get {return MyType.propertyName;} set {MyType.propertyName = value;} } 

真的应该是一个非常小的差异。 Jit编译器应该将call MyType.set_Property内联到字段加载中,但即使它不能由于错误。 我个人在谨慎方面犯了错误并坚持使用属性设置器和getter,因为方法体可能会发生变化,因此原始字段访问/突变可能还不够。

如果您想测试,可以强制发出的方法使用MethodImpl来关闭内联或优化。 然后比较差异,我真的怀疑它会很重要。