为什么没有编译器优化掉这段代码

时间:2015-06-29 11:15:31

标签: c# performance arcgis

我有一个代码使用第三方工具迭代一组点。

for (int i = 0; i < pcoll.PointCount; i++) { /* ... */ }

通过dotTrace进行分析时,我注意到每次迭代都会访问PointCount - proerty(见上图)

我预计编译器会优化此属性的值,但显然不会发生这种情况。也许这实际上是基于COM的第三方库中的问题,或者在收集信息时也在dotTrace self中。

我不确定这个主题是否更适合Gis.StackExchange。然而,也许有人知道在何种情况下优化不会发生或者如何发生。

3 个答案:

答案 0 :(得分:8)

简单地说,编译器如何知道pcoll.PointCount是否会在调用之间发生变化?它无法安全地假设值将保持不变,因此无法通过将第一次调用的值缓存到pcoll.PointCount来优化此代码。

答案 1 :(得分:2)

在此期间可能已发生变化。

确实,每次迭代测试i < pcoll.PointCount而非仅仅使用foreach(var point in pcoll)的原因之一正是因为认为该集合可能会在此期间发生变化,而且调查员不会#39; t保证应对他们列举的集合的变化。

这与例如通过局部变量访问的数组不同,因为通过局部变量访问的数组的Length可以改变的唯一方式是,如果在本地进行更改。

即便如此,值得记住的是,编译器经常会跳过一些明显的优化,因为它已经知道抖动也会产生相同的优化。

答案 2 :(得分:1)

字段的预期优化是正确的。但是属性有setter / getter(访问属性实际上是将它们称为方法),因此编译器将很难尝试优化它。

要修复,请将其设为字段或阅读一次

var max = pcoll.PointCount;
for (int i = 0; i < max; i++) { /* ... */ }