If you use data that is static for the duration of the loop,obtain it
@H_301_6@
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
@H_301_6@
do this optimization automatically. If they are properties,it is much
less likely. If the properties are virtual,it cannot be done
automatically.为什么编译器以这种方式优化属性“更不可能”,何时可以预期特定属性是否被优化?我假设在访问器中执行附加操作的属性对于编译器来说更难以优化,并且那些仅修改后备字段的属性更可能被优化,但是需要一些更具体的规则.自动实现的属性是否始终优化?
解决方法
首先,必须内联属性getter方法,使其变为等效的字段访问.当getter很小并且不会抛出异常时,这往往会起作用.这是必要的,因此优化器可以确保getter不依赖于可能受其他代码影响的状态.
请注意,如果Customer.Orders []索引器改变Customer.State属性,那么手动优化代码将是错误的.像这样的懒惰代码当然不太可能,但它从未像现在这样做过:)优化器必须确定.
其次,必须从循环体中提升现场访问代码.一种称为“不变代码运动”的优化.当抖动可以证明循环体内的语句不影响值时,可以使用简单的属性getter代码.
抖动优化器实现了它,但它并不是很好.在这种特殊情况下,当它无法内联CalculateTax()方法时,它很可能会放弃.本机编译器可以更加积极地优化它,它可以在内存上刻录内存和分析时间.抖动优化器必须满足相当困难的最后期限才能避免暂停.
当你自己这样做时,请记住优化器的约束.当然,如果这些方法确实存在您没有依赖的副作用,那就是相当难看的丑陋bug.只有当分析器告诉你这段代码在热门路径上时才会这样做,典型的~10%的代码实际上会影响执行时间.这里的概率很低,用于获取客户/订单数据的dbase查询比计算税收要贵几个数量级.幸运的是,像这样的代码转换也会使代码更具可读性,因此您通常可以免费获得代码.因人而异.
关于抖动优化的背景资料is here.