Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вопрос по array.length (https://javascript.ru/forum/misc/10427-vopros-po-array-length.html)

mexoboy 04.07.2010 16:44

Вопрос по array.length
 
Здравствуйте. Вот у меня тут возник спор с человеком, далеким от js - с "правильным программистом" C++.
Суть спора такова, он утверждает, что конструкция
for(i=0; i < arr.length; i++) не правильная, и что необходимо использовать конструкцию for(i=0, l = arr.length; i<l; i++), уверяя меня в том, что при каждом цикле for идет просчет arr.length. Но разве length не является внутренней переменной объекта array? Разве последней конструкцией мы не даем просто ссылку на arr.length?

Gozar 04.07.2010 17:02

mexoboy,
а слабо провести тест для обоих случаев и не полагаться на чьё-то мнение?

ps: найдете когда-нибудь это важным для ускорения и сможете доказать, я с удовольствием вас послушаю.

а так это сравнимо с прикручиванием педалей к истребителю

Riim 04.07.2010 17:55

Я всегда "length = arr.length" пишу. Это называется кеширование значений.

B@rmaley.e><e 04.07.2010 18:56

Цитата:

Сообщение от mexoboy
Разве последней конструкцией мы не даем просто ссылку на arr.length

Обратиться к свойству переменной дороже (в плане используемых операций), чем к самой переменной.

ЗЫ А еще правильней делать так
for(i=0, l = arr.length; i<l; ++i)
Или даже так
for(i=arr.length; i--;)

mexoboy 04.07.2010 18:57

2Gozar, ну вот как раз тесты ничего не показывают. при 5 миллионах итераций время всегда расходится в пользу разных методов, исходя из этого и был задан данный вопрос. Дело не в ускорении, а вообще в принципе работы array.length. Педали никто не собирается прикручивать, а спор остается спором. В другом другом языке вопросов-бы не было, но в js этот вопрос не тривиален.

P.s. Да, действительно, l не будет являться ссылкой =( Странно, что во многих фреймворках как раз пишут без объявления переменной length, а обращаются на прямую к arr.length .
var a = [1,2,3];
var l = a.length;
a.push(4);
console.log(l);

Octane 04.07.2010 19:04

Не факт, что length реализовано, как getter. Даже можно сказать, что скорее всего это обычное свойство, потому что Array.prototype.push.call(obj, 1) добавит length к obj во всех браузерах, поэтому обращение к length массива происходит не дольше, чем к любому другому свойству объекта, содержащему числовое значение, которое не пересчитывается каждый раз. Вот с NodeList уже другое дело, это динамическая структура.

Но я люблю гоняться за сверх скоростями и обычно пишу так:
var i = -1, length = array.length;
while (++i < length) {
    array[i]
}

если возможно, так:
var i = array.length;
while (i--) {
    array[i]
}

Riim 04.07.2010 19:11

Цитата:

Сообщение от mexoboy
ну вот как раз тесты ничего не показывают

еще от браузера многое зависит, плюс то, что Octane сказал.

Цитата:

Сообщение от B@rmaley.e><e
for(i=0, l = arr.length; i<l; ++i)

А здесь что изменилось?

Kolyaj 04.07.2010 19:12

Цитата:

Сообщение от mexoboy
при каждом цикле for идет просчет arr.length

Не идёт.

Цитата:

Сообщение от mexoboy
Но разве length не является внутренней переменной объекта array?

Является. Только свойством, а не внутренней переменной.

Цитата:

Сообщение от Octane
Не факт, что length реализовано, как getter.

Не реализовано, как геттер.

http://javascript.ru/ecma/part15#a-15.4.5.1

B@rmaley.e><e 04.07.2010 19:26

Цитата:

Сообщение от Riim
А здесь что изменилось?

Инкрементация.

e1f 04.07.2010 19:32

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 62169)
Обратиться к свойству переменной дороже (в плане используемых операций), чем к самой переменной.

ЗЫ А еще правильней делать так
for(i=0, l = arr.length; i<l; ++i)
Или даже так
for(i=arr.length; --i;)

Обожаю последний способ :) Но с постинкрементом. Чтоли протестировать, может, преинкремент еще быстрее ;)

UPD
Цитата:

Сообщение от B@rmaley.e><e (Сообщение 62179)
Инкрементация.

Эээ... А так мы разве не пропустим нулевой элемент массива?


Часовой пояс GMT +3, время: 12:04.