属性比字段慢

Hau*_*aus 14 c# jit field properties

似乎我遇到的每个帖子都达成了相同的共识:仅返回字段的属性由JIT内联,并且具有与字段几乎相同的性能.

但是,我目前的情况似乎并非如此.我的程序进行密集计算,访问许多属性,这些属性只是自动获取器和私有设置器.但是,在这种特殊情况下,我只是复制一个对象.

在启用优化的情况下在发布模式下分析代码会导致get对属性函数的许多调用.Copy()总呼叫总计约5.6ms.

属性基准

但是,当属性转换为字段时,函数运行速度比使用属性快6倍:

在此输入图像描述

与使用字段相比,比较两个属性的相等性似乎会产生更多的性能损失.这是类IEquatable实现的基准,使用相同的代码,但使用字段交换属性.

在此输入图像描述

如果JIT应该通过内联来优化属性,为什么会出现?我想保留属性,因为它们的访问控制方面非常方便,但如果它们这么慢,我会坚持使用字段.

编辑:似乎受此问题影响的一些(但不是全部)案例正在使用在接口中声明的属性.在这些情况下没有使用其他多态性,但在这些情况下,删除接口会将性能差异带入预期的水平.

编辑2:如前面的编辑​​所述,似乎问题的一部分是由于接口虚拟调用.经过更多调查后,似乎在CLR中运行基准测试正确地内联属性,但JetBrains dotTrace没有,即使选中"启用内联"也是如此.

AAA*_*ddd 3

不幸的是,除了尝试通过使用来帮助消除抖动之外,您无能为力

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Run Code Online (Sandbox Code Playgroud)

AggressiveInlined 如果可能的话,应该内联该方法。

现在从技术上讲,这只能在方法或构造函数上使用,但是您似乎可以在 getter 和 setter 本身上测试它。即它编译(虽然我还没有测试过)

public int someType
{
   [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
   get;
   [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
   set;
}
Run Code Online (Sandbox Code Playgroud)

注意:内联是一个令人惊奇的黑匣子,抖动可能感觉或不感觉,甚至属性也只是一个建议。另请注意,位数也可能会影响其内联内容。

最后,我认为您正在以正确的方式进行此操作,您应该使用基准标记器或分析器,并相应地进行微优化,