c# – 在循环期间保持静态的属性的编译器优化
我正在阅读
Improving .NET Application Performance and Scalability.标题为避免重复字段或属性访问的部分包含一个准则:
以下代码作为示例给出: 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]); } 文章指出:
为什么编译器以这种方式优化属性“更不可能”,何时可以预期特定属性是否被优化?我假设在访问器中执行附加操作的属性对于编译器来说更难以优化,并且那些仅修改后备字段的属性更可能被优化,但是需要一些更具体的规则.自动实现的属性是否始终优化? 解决方法
它需要抖动应用两个优化:
首先,必须内联属性getter方法,使其变为等效的字段访问.当getter很小并且不会抛出异常时,这往往会起作用.这是必要的,因此优化器可以确保getter不依赖于可能受其他代码影响的状态. 请注意,如果Customer.Orders []索引器改变Customer.State属性,那么手动优化代码将是错误的.像这样的懒惰代码当然不太可能,但它从未像现在这样做过:)优化器必须确定. 其次,必须从循环体中提升现场访问代码.一种称为“不变代码运动”的优化.当抖动可以证明循环体内的语句不影响值时,可以使用简单的属性getter代码. 抖动优化器实现了它,但它并不是很好.在这种特殊情况下,当它无法内联CalculateTax()方法时,它很可能会放弃.本机编译器可以更加积极地优化它,它可以在内存上刻录内存和分析时间.抖动优化器必须满足相当困难的最后期限才能避免暂停. 当你自己这样做时,请记住优化器的约束.当然,如果这些方法确实存在您没有依赖的副作用,那就是相当难看的丑陋bug.只有当分析器告诉你这段代码在热门路径上时才会这样做,典型的~10%的代码实际上会影响执行时间.这里的概率很低,用于获取客户/订单数据的dbase查询比计算税收要贵几个数量级.幸运的是,像这样的代码转换也会使代码更具可读性,因此您通常可以免费获得代码.因人而异. 关于抖动优化的背景资料is here. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |