似乎我看到的每篇文章都得出了同样的结论:仅返回字段的属性会被JIT内联,与字段几乎相同的性能。
然而,在我的当前情况下,似乎并非如此。我的程序进行了许多密集的计算,访问了许多仅仅是自动Getter和私有Setter的属性。但在这种特殊情况下,我只是复制一个对象。
启用优化模式,在发布模式下对代码进行分析,结果导致了对属性的get
函数的许多调用。对Copy()
的调用总共达到了约5.6毫秒。
但是,当将属性转换为字段时,该函数运行的速度比使用属性时快了6倍:
比较两个属性的相等性与使用字段相比似乎会带来更大的性能损失。以下是一个类的IEquatable
实现的基准测试,使用相同的代码但使用字段替换属性。
如果JIT应该通过内联优化属性,为什么会出现这种情况?我想保留属性,因为它们的访问控制很方便,但如果它们变得太慢,我就会坚持使用字段。
编辑:看起来受到此问题影响的一些(但不是全部)情况正在使用在接口中声明的属性。在这些情况下,没有使用其他多态性,但删除接口则在这些情况下使性能变化达到预期水平。
编辑2:如上一次编辑所述,似乎部分问题是由于接口虚拟调用引起的。经过更多调查,似乎在CLR中运行基准测试可以正确地内联属性,但即使勾选了“启用内联”,JetBrains dotTrace也不会内联。
obj.Property = 5;
和obj.Field = 5;
在调试时,当我打开 Dissassembly 窗口时,我可以看到这两个调用是相同的。因此,我假设您的自动属性访问的对象有点大,因此它们没有被内联... 有许多内联规则,您可以检查其中一些 https://dev59.com/RW445IYBdhLWcg3w3N6z - Hasan Emrah Süngüvar a = obj.PropertyA.Something(); var b = obj.PropertyA.Anotherthing(); var c = obj.PropertyA.OneAnotherthing();
我建议将PropertyA
存储到本地变量中,然后再调用方法等:var localProp = obj.PropertyA;
- Hasan Emrah Süngü