Дорого ли делать array.length или list.count в цикле - PullRequest
20 голосов
/ 04 ноября 2008

Я знаю, что в JavaScript создание цикла for наподобие этого: for(int i = 0; i < arr.length; i++) является дорогостоящим, поскольку каждый раз вычисляет длину массива. Является ли такое поведение дорогостоящим в c # для списков и массивов? Или во время компиляции это оптимизировано? А как насчет других языков, таких как Java, как это обрабатывается?

Ответы [ 6 ]

27 голосов
/ 04 ноября 2008

Это не дорого в C #. Во-первых, здесь нет «расчета»: запрос длины в основном является элементарной операцией благодаря встраиванию. И, во-вторых, поскольку ( согласно его разработчикам ), компилятор распознает этот шаблон доступа и фактически оптимизирует любые (избыточные) проверки границ для доступа к элементам массива.

И, кстати, я полагаю, что нечто подобное верно для современных виртуальных машин JavaScript, и если это не так, то это произойдет очень скоро, поскольку это тривиальная оптимизация.

5 голосов
/ 04 ноября 2008
  1. Все массивы .Net имеют поле, содержащее длину массива, поэтому длина вычисляется не при использовании, а во время создания.

  2. . Виртуальная машина .Net очень хорошо устраняет проверки границ, когда это возможно, это один из тех случаев, когда проверка границ перемещается за пределы цикла (в большинстве ситуаций, а если нет, то это всего лишь две инструкции) ).

Edit:

Устранение проверки границ массива

3 голосов
/ 04 ноября 2008

Почти на любом языке ответ будет "это зависит".

В основном это зависит от того, достаточно ли умен компилятор, чтобы определить, может ли длина списка или массива измениться, пока вы находитесь в цикле.

Это вряд ли будет определено спецификацией языка.

Так что, вероятно, можно предположить, что компиляция не сможет понять это. Если вы действительно уверены, что длина объекта не изменится, не стесняйтесь сначала рассчитать длину и использовать ее в своих конструкциях управления циклом.

Но остерегайтесь других тем ...

0 голосов
/ 04 ноября 2008

Полагаю, если вы используете метод расширения Linq Count (), то он может вычисляться каждый раз, когда вызывается.

0 голосов
/ 04 ноября 2008

Это также будет зависеть от того, выполняет ли получатель вычисления или получает доступ к известному значению.

0 голосов
/ 04 ноября 2008

Если это что-то похожее на Java, это должна быть операция O (1).

Мне показалась полезной следующая ссылка: http://www.devguru.com/Technologies/Ecmascript/Quickref/array.html

...