почему обращение к window быстрее, чем к локальной переменной?
в общем, написал себе быструю функцию для поиска элемента по имени тега
сделал себе поле для тестов,чтобы посмотреть, на сколько она быстрая. вот примеры с HTML ( можно запускать )
<button onclick="loop()">запустить цикл</button>
<br>
длина очереди : <b></b> <br> <br>
что добавить ? <br>
<input value="alert(5);">
<br> <br>
<button>добавить</button> <button>убрать</button>
<br> <br>
<button>исполнить</button>
<script>
// кеш. при изменении DOM буду обновлять. но это все равно неважно
els = window.document.body.children;
b = els.length;
function ge(tagname){
tagname = tagname.toUpperCase();
var i = 0, el
while(i++ < b){
if( (el = els[i]).tagName === tagname )
break;
}
return el;
}
/* сам цикл для просмотра сожранного времени */
function loop(){
var count = 100000;
console.time("search");
while( count-->0 ) {
ge('input')
}
console.timeEnd("search");
console.log( ge('input') ) // проверим еще раз, нашел ли элемент
};
loop();
</script>
при таком раскладе у меня FF сжирает 390-410 ( среднее, 400 ) хром ест 145 ms ( ого :) ) пытаюсь закешировать window.b в локальной b
<button onclick="loop()">запустить цикл</button>
<br>
длина очереди : <b></b> <br> <br>
что добавить ? <br>
<input value="alert(5);">
<br> <br>
<button>добавить</button> <button>убрать</button>
<br> <br>
<button>исполнить</button>
<script>
// кеш. при изменении DOM буду обновлять. но это все равно неважно
els = window.document.body.children;
b = els.length;
function ge(tagname){
tagname = tagname.toUpperCase();
var i = 0, el, *!* b = window.b */!*
while(i++ < b){
if( (el = els[i]).tagName === tagname )
break;
}
return el;
}
/* сам цикл для просмотра сожранного времени */
function loop(){
var count = 100000;
console.time("search");
while( count-->0 ) {
ge('input')
}
console.timeEnd("search");
console.log( ge('input') ) // проверим еще раз, нашел ли элемент
};
loop();
</script>
теперь повторялка сжирает 430-460 ms ( среднее - 445 ) хром ест 180ms ( стабильно 177-181) т.е. на 8% медленней. в чем прикол ??? также, еще вопрос. только насчет while в той же функции ge почему этот цикл (снизу) быстрее .. ( время 400 )
*!*while(i++ < b){*/!*
if( (el = els[i]).tagName === tagname )
break;
*!*}*/!*
.. быстрее этого ??
*!*do{*/!*
if( (el = els[i]).tagName === tagname )
break;
*!*} while(i++ < b)*/!*
среднее время второго 481 ms. на 17% медленней. почему же так???? больше всего удивления на первый случай вот еще насчет window и local scope хром ест 185-198ms
<button onclick="loop()">запустить цикл</button>
<br>
длина очереди : <b></b> <br> <br>
что добавить ? <br>
<input value="alert(5);">
<br> <br>
<button>добавить</button> <button>убрать</button>
<br> <br>
<button>исполнить</button>
<script>
els = window.document.body.children;
b = els.length;
function ge(tagname){
tagname = tagname.toUpperCase();
var i = 0, el, *!* els = window.els, b = els.length; */!*
while(i++ < b){
if( (el = els[i]).tagName === tagname )
break;
}
return el;
}
/* сам цикл для просмотра сожранного времени */
function loop(){
var count = 100000;
console.time("search");
while( count-->0 ) {
ge('input')
}
console.timeEnd("search");
console.log( ge('input') ) // проверим еще раз, нашел ли элемент
};
loop();
</script>
эта функция жрет 460-470 ms ( среднее, 465ms ) P.S. не надо , пожалуйста, мне говорить, что есть куча быстрых фреймворков, всякого т.д . )) |
отвечу сам себе, почему этот цикл (снизу) быстрее .. ( время 400 )
*!*while(i++ < b){*/!*
if( (el = els[i]).tagName === tagname )
break;
*!*}*/!*
.. быстрее этого ??
*!*do{*/!*
if( (el = els[i]).tagName === tagname )
break;
*!*} while(i++ < b)*/!*
среднее время второго 481 ms. на 17% медленней. потому что do{statements}while(bool) сначала делает statements, а потом "думает" в bool, исполнять ли ему цикл еще раз... а вот while(bool){statements} сначала решает в bool, исполнять ли ему statements,или нет. таким образом, while(bool){statements} не делает лишнюю работу, которую делает do{statements}while(bool) я это так понял :)) сори за кросспост. надо было апнуть тему. |
Цитата:
В do..while на одну итерацию больше в этом случае, вот оно и медленнее обычного while. |
Цитата:
... а что насчет window ? |
Цитата:
С for та же ситуация. for (i = 0; i++ < 3; ) будет работать быстрее, чем for (i = 0; i++ < 4; ). Меньше итераций — больше скорость. Это же очевидно. Цитата:
Почти уверен, что к сути относится строчки три, не больше. Лень вникать. |
по теме кода там мало. много кода из-за того, что там html везде понапихан и циклы для замера времени исполнения :)
весь вопрос заключается в этом : "почему без var b = window.b функция работает быстрее?" по идее должна медленнее
els = window.document.body.children;
b = els.length;
function ge(tagname){
tagname = tagname.toUpperCase();
var i = 0, el, *!* b = window.b */!*
while(i++ < b){
if( (el = els[i]).tagName === tagname )
break;
}
return el;
}
и еще один парадокс затестил сейчас же
while(i < b){
if( (el = els[i++]).tagName === tagname ) break;
if( (el = els[i++]).tagName === tagname ) break;
}
если цикл такой (сверху), время исполнения в FF 460, Chrome - 150. итераций в 2 раза больше! если добавить еще if( foo ) break;, скорость исполнения уменьшается на ~5-7 ms .. а если такой
while(i++ < b){
if( (el = els[i]).tagName === tagname )
break;
}
если цикл такой (сверху), время исполнения в FF 390, Chrome - 120. ведь итераций больше? ?????? |
Цитата:
|
То есть меньше
)) Я отвлекся.) |
Цитата:
while(i--) {}
|
var el,i = window.b;
while( i-- > 0 ){
if( (el = els[i]).tagName === tagname )
break;
}
FF - 840ms , хром - 432ms
els = window.document.body.children;
b = els.length;
function ge(tagname){
tagname = tagname.toUpperCase();
var el;
*!*if(b<0) b = els.length;*/!*
while( b-- > 0 )
if( (el = els[b]).tagName === tagname )
break;
return el;
}
. вот так вот ФФ - 570, хром - 315
while( window.b-- > 0 ){
if( (el = els[window.b]).tagName === tagname )
break;
}
в ФФ - 70, в хроме 50 .нипонять |
melky, а зачем > 0 , если можно писать так :
while( b-- ) ? |
а насчет window.b и локальной переменной b , может быстрей потому что когда обращается к локальной то интепретатор делает это так:
[[Scope]].b , а если через window.b то на прямую обращается к window |
В разных браузерах код исполняется по разному. Вот и разница в скорости.
Цитата:
|
| Часовой пояс GMT +3, время: 15:50. |