我有一个代码使用第三方工具迭代一组点。
for (int i = 0; i < pcoll.PointCount; i++) { /* ... */ }
通过dotTrace进行分析时,我注意到每次迭代都会访问PointCount
- proerty(见上图)
我预计编译器会优化此属性的值,但显然不会发生这种情况。也许这实际上是基于COM的第三方库中的问题,或者在收集信息时也在dotTrace self中。
我不确定这个主题是否更适合Gis.StackExchange。然而,也许有人知道在何种情况下优化不会发生或者如何发生。
答案 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++) { /* ... */ }