属性比字段慢

时间:2018-12-14 02:39:05

标签: c# properties field jit

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

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

在启用了优化的情况下以发布模式对代码进行性能分析,导致多次调用该属性的get函数。对Copy()的呼叫总计约5.6毫秒。

Properties benchmark

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

enter image description here

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

enter image description here

如果JIT应该通过内联属性来优化属性,为什么会发生这种情况?我想保留属性,因为它们的访问控制方面非常方便,但是如果它们慢得多,我会坚持使用字段。

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

编辑2:如上一次编辑所述,似乎部分问题是由于接口虚拟调用引起的。经过更多调查,似乎在CLR中运行基准测试可以正确地内联属性,但是即使选中了“启用内联”,JetBrains dotTrace也无法正确内联。

1 个答案:

答案 0 :(得分:2)

不幸的是,除了尝试通过使用

来帮助JITTER之外,您无能为力
[MethodImpl(MethodImplOptions.AggressiveInlining)]
  

AggressiveInlining 该方法应尽可能内联。

现在从技术上讲,它只能在方法或构造函数上使用,但是您似乎可以在吸气剂上对其进行测试并自行设置。即它编译(虽然我还没有测试过)

public int someType
{
   [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
   get;
   [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
   set;
}

注意 :内联是一个令人惊讶的黑匣子,抖动可能与否,即使该属性仅是一个建议。还请注意,位数也可能会影响其内联。

最后,我认为您正在按照正确的方式进行操作,您应该只使用bechmarker或profiler,并进行相应的微优化,