Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 31.03.2011, 10:30
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

почему обращение к 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. не надо , пожалуйста, мне говорить, что есть куча быстрых фреймворков, всякого т.д . ))

Последний раз редактировалось melky, 01.04.2011 в 20:23.
Ответить с цитированием
  #2 (permalink)  
Старый 31.03.2011, 23:56
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

отвечу сам себе, почему этот цикл (снизу) быстрее .. ( время 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)

я это так понял )

сори за кросспост. надо было апнуть тему.
Ответить с цитированием
  #3 (permalink)  
Старый 01.04.2011, 11:19
Профессор
Отправить личное сообщение для Matre Посмотреть профиль Найти все сообщения от Matre
 
Регистрация: 07.01.2011
Сообщений: 582

Цитата:
я это так понял
Неправильно понял.
В do..while на одну итерацию больше в этом случае, вот оно и медленнее обычного while.
Ответить с цитированием
  #4 (permalink)  
Старый 01.04.2011, 19:49
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Цитата:
потому что do{statements}while(bool) сначала делает statements, а потом "думает" в bool, исполнять ли ему цикл еще раз
Это разве не одно и то же?

...

а что насчет window ?
Ответить с цитированием
  #5 (permalink)  
Старый 01.04.2011, 20:01
Профессор
Отправить личное сообщение для Matre Посмотреть профиль Найти все сообщения от Matre
 
Регистрация: 07.01.2011
Сообщений: 582

Цитата:
Это разве не одно и то же?
Нет.
С for та же ситуация.
for (i = 0; i++ < 3; ) будет работать быстрее, чем for (i = 0; i++ < 4; ).
Меньше итераций — больше скорость. Это же очевидно.

Цитата:
а что насчет window ?
Там столько кода написано...
Почти уверен, что к сути относится строчки три, не больше.
Лень вникать.
Ответить с цитированием
  #6 (permalink)  
Старый 01.04.2011, 20:15
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

по теме кода там мало. много кода из-за того, что там 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. ведь итераций больше?

??????

Последний раз редактировалось melky, 02.04.2011 в 13:51.
Ответить с цитированием
  #7 (permalink)  
Старый 02.04.2011, 11:09
Профессор
Отправить личное сообщение для Matre Посмотреть профиль Найти все сообщения от Matre
 
Регистрация: 07.01.2011
Сообщений: 582

Цитата:
ведь итераций больше?
Меньше.
Ответить с цитированием
  #8 (permalink)  
Старый 02.04.2011, 13:48
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

То есть меньше

))
Я отвлекся.)
Ответить с цитированием
  #9 (permalink)  
Старый 02.04.2011, 14:03
Особый гость
Посмотреть профиль Найти все сообщения от monolithed
 
Регистрация: 02.04.2010
Сообщений: 4,260

Сообщение от melky
еще вопрос. только насчет while
этот попробуйте:
while(i--) {}
Ответить с цитированием
  #10 (permalink)  
Старый 02.04.2011, 14:08
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

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, 02.04.2011 в 15:05.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обращение к глобальной переменной из jQuery Иван Алексеев jQuery 6 13.08.2010 20:56
Почему код работает? (обращение к форме из window) Василий Б. Элементы интерфейса 10 21.04.2010 10:10