gpt4 book ai didi

c# - 编译器优化在循环期间保持静态的属性

转载 作者:太空狗 更新时间:2023-10-29 21:26:53 27 4
gpt4 key购买 nike

我正在阅读 Improving .NET Application Performance and Scalability .标题为避免重复字段或属性访问的部分包含一个指南:

If you use data that is static for the duration of the loop, obtain it before the loop instead of repeatedly accessing a field or property.

以下代码作为示例给出:

for (int item = 0; item < Customer.Orders.Count; item++)
{
CalculateTax(Customer.State, Customer.Zip, Customer.Orders[item]);
}

成为

string state = Customer.State;
string zip = Customer.Zip;
int count = Customers.Orders.Count;
for (int item = 0; item < count; item++)
{
CalculateTax(state, zip, Customer.Orders[item]);
}

文章指出:

Note that if these are fields, it may be possible for the compiler to do this optimization automatically. If they are properties, it is much less likely. If the properties are virtual, it cannot be done automatically.

为什么编译器以这种方式优化属性的可能性“大大降低”,以及何时可以期望某个特定属性被优化或不被优化?我会假设在访问器中执行额外操作的属性对于编译器来说更难优化,而那些只修改支持字段的属性更有可能被优化,但想要一些更具体的规则。自动实现的属性是否总是经过优化?

最佳答案

它需要抖动应用两个优化:

首先,必须内联属性 getter 方法,以便它变成等同于字段访问的方法。当 setter/getter 很小并且不会抛出异常时,这往往会起作用。这是必要的,以便优化器可以确保 getter 不依赖可能受其他代码影响的状态。

请注意,如果 Customer.Orders[] 索引器会更改 Customer.State 属性,那么手动优化的代码将如何出错。像这样的惰性代码当然不太可能,但也不是从来没有这样做过:)优化器必须确定。

其次,必须将字段访问代码提升到循环体之外。称为“不变代码运动”的优化。当抖动可以证明循环体内的语句不影响值时,适用于简单的属性 getter 代码。

抖动优化器实现了它,但它并不出色。在这种特殊情况下,它很可能会在无法内联 CalculateTax() 方法时放弃。 native 编译器对其进行更积极的优化,它可以负担得起消耗内存和分析时间。抖动优化器必须满足一个非常严格的截止日期以避免暂停。

当您自己执行此操作时,请牢记优化器的约束。如果这些方法确实有您没有预料到的副作用,那当然是非常丑陋的错误。并且在探查器告诉您此代码位于热路径上时执行此操作,通常约 10% 的代码会实际影响执行时间。这里的可能性很低,获取客户/订单数据的数据库查询比计算税收要贵几个数量级。幸运的是,像这样的代码转换也往往使代码更具可读性,因此您通常可以免费获得它。 YMMV.

关于抖动优化的背景资料 is here .

关于c# - 编译器优化在循环期间保持静态的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35093144/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com