在循环中执行array.length或list.count是否代价高昂

时间:2008-11-04 18:52:56

标签: c# compiler-construction performance language-features

我知道在JavaScript中,创建一个这样的for循环:for(int i = 0; i < arr.length; i++)代价很高,因为它每次都会计算数组长度。 对于列表和数组,这种行为在c#中是否代价高昂。或者在编译时它是否经过优化?还有其他语言如Java,这是如何处理的?

6 个答案:

答案 0 :(得分:27)

C#中代价高昂。一方面,没有“计算”:由于内联,查询长度基本上是一个基本操作。其次,因为(according to its developers),编译器会识别这种访问模式,并且实际上会优化任何(冗余)边界检查以访问数组元素。

顺便说一句,我相信现代JavaScript虚拟机也有类似的东西,如果还没有,那么很快就会发生,因为这是一个微不足道的优化。

答案 1 :(得分:5)

  1. 所有.Net数组都有一个包含数组长度的字段,因此在使用时但不是在创建时计算长度。

  2. .Net虚拟机非常擅长在可能的情况下消除边界检查,这是其中一种情况,其中边界检查移出循环(在大多数情况下,如果不是,它只是2个指令开销) )。

  3. 编辑:

    Array Bounds Check Elimination

答案 2 :(得分:3)

几乎在任何语言中,答案都是“它取决于”。

大多数情况下,它取决于编译器是否足够聪明,能够判断在循环中列表或数组的长度是否会发生变化。

但这不太可能由语言规范定义。

因此,可以安全地假设编译可能无法解决这个问题。如果你真的相信对象的长度不会改变,可以先自由计算长度并在循环控制结构中使用它。

但要注意其他线索......

答案 3 :(得分:0)

如果它像Java一样,它应该是O(1)操作。

我发现以下链接很有用:http://www.devguru.com/Technologies/Ecmascript/Quickref/array.html

答案 4 :(得分:0)

它还取决于该getter是进行计算还是访问已知值。

答案 5 :(得分:0)

我相信如果你使用Linq Count()扩展方法,那么它可以在每次调用时计算。