我知道在下面的代码数组'长度'每次循环迭代都不会调用property,因为Jit编译器足够聪明,可以将它识别为属性(而不是方法),并优化代码只在内部存储临时变量中的值时调用它:
Int32[] myArr = new Int32[100];
for(Int32 index = 0; index < myArr.Length; index++) {
// Do something with the current item
}
因此,开发人员无需通过将长度缓存到局部变量来尝试优化它。 我的问题:.Net中的所有集合类型都是如此吗?例如,假设我有一个列表并打电话&#39; Count&#39; for循环中的属性。我不应该对此进行优化吗?
答案 0 :(得分:8)
我知道在下面的代码数组中,每次循环迭代都不调用'Length'属性,因为Jit编译器足够聪明,可以将它识别为属性(不是方法)
虽然从类型系统的角度来看,长度是一个属性,但从抖动的角度来看,它只是一个加载数组长度的特殊指令。这就是使抖动能够执行此优化的原因。
我还注意到有一个更大的优化,你没有提到。检查长度很便宜。这里更大的优化是抖动可以忽略对数组中索引操作的检查,因为它知道循环变量将始终位于数组的边界内。由于这些检查可以抛出异常,通过消除它们,抖动可以更容易地分析方法的控制流,因此可以对方法的其余部分进行更好的优化。
.Net中的所有集合类型都是如此吗?
如果能够证明这样做是正确的,那么允许允许对其他集合类型进行优化。无论它是否真的这样做,你都可以使用科学进行测试;观察抖动生成的代码,看看它是否有这种优化。我的猜测是抖动没有这种优化。
例如,假设我有一个List并在for循环中调用'Count'属性。我不应该优化这个吗?
现在我们来看问题的真正症结。绝对不应该优化它。优化是非常昂贵的;您的雇主会为您花费优化代码的每一分钟付费,因此您应该优化产生最大用户可观察胜利的事物。获取列表的计数需要几纳秒。世界上没有任何程序在市场上取得成功取决于某人是否从一个不必要地检查列表计数的循环中移除了几纳秒。
花时间进行效果优化的方法首先是以客户为中心的目标。这就是让你知道什么时候你可以停止担心性能并把钱花在更重要的事情上。其次,每天衡量这一目标的进展情况。第三,如果并且仅在您未达到目标时,使用分析器来确定代码实际上不具备足够性能的位置。然后优化那个东西,那个东西。
纳米优化不是设计性能的方法。它们只会使代码更难以阅读和维护。在分析绩效时使用良好的工程学科,而不是一系列提示和技巧。