Приведенный способ среди всех, которые я видел, является средним (как по быстродействию, так и по сложности реализации). Действительно хорошим советом является отделение данных от DOM (KAdot). Это увеличит скорость.
Как-нибудь напишу статьи про:
1) построение HTML с помощью JS;
2) сортировку данных в таблицах.
Автору плюсик за старание.
Я не буду переходить на личности, потому что троллинг слишком толстый. Сейчас вы сказали какую-то х**ту. Мне интересно вы хоть сами понимаете о чем говорите?
1) Под аргументами в данном имелись в виду именованные параметры функций (и вы это знали, когда сказали, что пример нечестен), а вы переходите на вообще не в тему объект arguments.
2) Движки ВСЕГДА используют стек для работы с аргументами. А пример доказал, что это происходит и для локальных переменных.
3) Код:
function f(){
var a=arguments[0],
b=arguments[1],
c=arguments[2];
};
Аргумент ф-и и локальная переменная — разные вещи, согласитесь?
Абсолютно несогласен.
Мой главный довод: аргументы функций ведут себя так же, как и локальные переменные: 1) они уничтожатся по завершению работы функции (если не замкнуты); 2) их можно замкнуть; 3) var a,b,c… даёт ТОТ же результат; 4) их нельзя удалить.
Приведите хотя бы один аргумент против.
Эффект от нескольких сэкономленных переменных проявится более-менее заметно, если у вас десятки и сотни тысяч вызовов. Но делать рекурсию такой глубины — крайне глупое, неэффективное и непродуманное решение. У вас оверхед на вход/выход в функцию и расход памяти на стеке перевесит все оптимизации. От такой рекурсии надо избавляться.
Ситуация напоминает анекдот «Мужики, мы же взрослые люди! Давайте просто достанем и померяемся».
Действительно, к чему все эти дурацкие споры? Я взял и проверил:
(function init(){
COUNTER=0;
(function recourse(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1){//легкая шизофазия в виде 52-х локальных переменных
COUNTER++;
arguments.callee(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1);
});
})();
Chrome упал на 2217, IE — на 1867, Firefox вообще завис. Маразм, конечно, маразмом, но ресурсы тоже не резиновые.
Во вторых — опять же, читайте следующий совет: для рекурсии используйте замыкания.
Подтверждаем кодом:
1) Про память — бред, если вам надо освободить память, напишите n = null; но НЕ ИСПОЛЬЗУЙТЕ одну переменную для разных целей, отлаживать замучаетесь
Перечитайте статью. Там написано, что лучше всего это проявляется в рекурсивных функциях.
2) пример неудачный. Вместо того, чтобы ставить 100/1000 обработчиков onclick, лучше поставить один на родительском элементе.
Суть была в том, чтобы показать, как замыкание меняется функцией без замыкания. Но насчёт родительского — эта идея лучше.
Про события перетаскивания — эпический бред. Вы учли, что навеивание/снятие обработчика —это тоже обращение к ДОМу, перестроение внутренних структур данных в браузере, и если вы будет это делать с частотой 100 раз в секунду, это не очень правильно. Гораздо правильнее ждать нажатия кнопки мыши (начало перетаскивания) на нужном объекте, и при нажатии — ставить обработчик onmousemove, при отпускании — снимать.
Фэйспалм.жпг. Вы мыслите слишком узко. Как по-вашему анимировать элемент, когда по нему происходит просто пробегание курсора, например, как в нижней панели MacOS. Совет про отслеживание нажатие мыши, может быть и дельный, но только если действительно требуется нажатие. Но в целом замечание учту.
Троттлить (ограничивать частоту вызова) стоит функцию onresize, так как когда юзер ресайзит окно, пересчитывается и перерисовывается вся страница, и если вы еще будете свои скрипты пересчитыать, это может убить отзывчивость браузера окончательно.
Ограничение делается таким же способом, как и для движения мыши.
Честно — это их проблемы. Данная статья содержит советы в первую очередь необходимые для критических участков кода. Их использование совершенно необязательно в коде, который не будет вызывать больших нагрузок.
Я понимаю, что советы могут казаться безосновательными, потому что почти нету их оказательств. Устраняю этот недостаток. Следующий код я использовал для определения времени выполнения того или иного кода:
(function init(){
var x=document.getElementById("x");
var test=function test(fnc){
var d=new Date;
for(var i=0;i<10000;i+=1)
fnc();
alert(new Date()-d);
};
test(function yourfunc(){
//здесь ваш код который нужно сравнить с другим кодом по скорости
});
test(function yourfunc2(){
//здесь ваш код который нужно сравнить с другим кодом по скорости
});
})();
Насколько я могу представить, этот код действительно даст знать, который из приведенных кодов быстрее. Правда, необходимо провести тестов этак 10, чтобы убедиться в этом.
Если вы меня поддержите, я напишу вообще отдельную статью про переменные в JavaScript. Поверьте, информация есть и её действительно хватает на целую статью. Причем это не будет копипастой с javascript.ru или из книжки Д. Флэнагана. Я думаю, даже матёрым знатокам будет что оттуда вынести.
Может быть, вот так и будет положено начало серии моих статей по обучению JS :)
Очень хочется ругнуться, но сдержался.
Вы хотя бы знаете, в какой области видимости выполняется код?
1) Особенность переменных, объявленных не внутри функции, в том, что они становятся глобальными (т.е. записываются в window);
2) На основе предыдущей особенности у вас фактически получается код:
alert(some_undefined_var);//обращаемся к несуществующей переменной
т.е. после удаления глобальной переменной уже не играет роли, создавалось ли что-то ранее с таким именем или нет. Её нет и всё.
Вот и получаем ошибку.
А речь шла именно о ЛОКАЛЬНЫХ переменных.
Я думаю, не все поняли мою идею: я не призываю использовать те же переменные для новых целей.
Суть в том, что если вы насоздаёте новых переменных внутри рекурсивной функции, то смотрите, чтобы стек не переполнился уже на сотом вызове.
1) Замыкание создаётся ПРИ СОЗДАНИИ ФУНКЦИИ, которая будет содержать замыкание;
2) Функции-обёртки — это функции, которые сами по себе не несут важного смысла, но используются, чтобы единожды (по умолчанию) запустить изолированный код. Вот вам пример (хоть и тривиальный):
(function init(){//функция-обёртка
var JUST_A_VAR=0;
...
})();
(function init2(){//функция-обёртка 2
var JUST_A_VAR=0;//используется переменная с таким же именем, но она локальная только для этой функции, поэтому не имеет никакого отношения к переменной с таким же именем в прошлой функции
...
})();
Пример не совсем из оптимизации, но у меня на практике было, что за мной дописывали код и использовали уже созданную переменную (не зная этого), что привело к неожидаенным результатам.
Еще они нужны, чтобы локальные переменные не просочились в объект window.
Например, с помощью функции-обёртки инициализируется JQuery.
Если честно, я думаю вообще переписать этот раздел, потому что он действительно сложен для понимания тем, кто недавно знаком с языком.
Просто когда начинаю собирать информацию, там на отдельную статью тянет :)
А насчёт паузы я писал отдельно, но могу еще уточнить: чтобы понять, сколько раз выполняется функция, выполните следующий код:
var counter=0,
handle=setInterval(function f(){counter++;},0);
setTimeout(function f2(){
clearTimeout(handle);
alert(counter);
},1000);
Смысл в том, что смотрится, сколько раз за одну секунду запустится функция с использованием таймаута. Это значение значение будет скорее всего с дробной частью (которая возникает из-за того, что было отдано недостаточно процессорного времени браузеру), которую нужно будет округлить вниз (floor). Вы сможете убедиться в этом, когда проведёте тест несколько раз: все значения будут меньше либо равны некоторому числу, если на которое разделить 1000 мс из теста, то получится число, очень близкое к целому. Если вы не поняли вышесказанного, то на примере разберётесь.
Пример: у меня Firefox показал 246 раз, Chrome 16 — 197 раз, IE9 — 247 раз, Opera12.0a — 99.
Если разделить 1000 на полученное количество раз, то получим актуальный интервал.
1000 мс/246≈4 мс — для Firefox
1000 мс/197≈5 мс — для Chrome (видимо, минимальный интервал чуть повысили)
1000 мс/247≈4 мс — для IE9 (прошлый тест проводился на восьмой версии)
1000 мс/99≈10 мс — для Opera12.0a
Тесты будут достоверными, если кроме браузера больше никакая программа не будет грузить процессор.
Как-нибудь напишу статьи про:
1) построение HTML с помощью JS;
2) сортировку данных в таблицах.
Автору плюсик за старание.
1) Под аргументами в данном имелись в виду именованные параметры функций (и вы это знали, когда сказали, что пример нечестен), а вы переходите на вообще не в тему объект arguments.
2) Движки ВСЕГДА используют стек для работы с аргументами. А пример доказал, что это происходит и для локальных переменных.
3) Код:
равен по смыслу (но не по скорости) коду:
Кто не согласен — приводите доказательства.
Абсолютно несогласен.
Мой главный довод: аргументы функций ведут себя так же, как и локальные переменные: 1) они уничтожатся по завершению работы функции (если не замкнуты); 2) их можно замкнуть; 3) var a,b,c… даёт ТОТ же результат; 4) их нельзя удалить.
Приведите хотя бы один аргумент против.
Ситуация напоминает анекдот «Мужики, мы же взрослые люди! Давайте просто достанем и померяемся».
Действительно, к чему все эти дурацкие споры? Я взял и проверил:
Chrome упал на 2217, IE — на 1867, Firefox вообще завис. Маразм, конечно, маразмом, но ресурсы тоже не резиновые.
Во вторых — опять же, читайте следующий совет: для рекурсии используйте замыкания.
Подтверждаем кодом:
Chrome — 18k+, IE — 4377.
Если я не прав — укажите, где.
Перечитайте статью. Там написано, что лучше всего это проявляется в рекурсивных функциях.
Суть была в том, чтобы показать, как замыкание меняется функцией без замыкания. Но насчёт родительского — эта идея лучше.
Фэйспалм.жпг. Вы мыслите слишком узко. Как по-вашему анимировать элемент, когда по нему происходит просто пробегание курсора, например, как в нижней панели MacOS. Совет про отслеживание нажатие мыши, может быть и дельный, но только если действительно требуется нажатие. Но в целом замечание учту.
Ограничение делается таким же способом, как и для движения мыши.
Насколько я могу представить, этот код действительно даст знать, который из приведенных кодов быстрее. Правда, необходимо провести тестов этак 10, чтобы убедиться в этом.
Может быть, вот так и будет положено начало серии моих статей по обучению JS :)
Вы хотя бы знаете, в какой области видимости выполняется код?
1) Особенность переменных, объявленных не внутри функции, в том, что они становятся глобальными (т.е. записываются в window);
2) На основе предыдущей особенности у вас фактически получается код:
т.е. после удаления глобальной переменной уже не играет роли, создавалось ли что-то ранее с таким именем или нет. Её нет и всё.
Вот и получаем ошибку.
А речь шла именно о ЛОКАЛЬНЫХ переменных.
Суть в том, что если вы насоздаёте новых переменных внутри рекурсивной функции, то смотрите, чтобы стек не переполнился уже на сотом вызове.
Во-вторых, без обёртки код выполнится в глобальной области видимости, т.е. переменные будут записаны в window.
2) Функции-обёртки — это функции, которые сами по себе не несут важного смысла, но используются, чтобы единожды (по умолчанию) запустить изолированный код. Вот вам пример (хоть и тривиальный):
Пример не совсем из оптимизации, но у меня на практике было, что за мной дописывали код и использовали уже созданную переменную (не зная этого), что привело к неожидаенным результатам.
Еще они нужны, чтобы локальные переменные не просочились в объект window.
Например, с помощью функции-обёртки инициализируется JQuery.
Просто когда начинаю собирать информацию, там на отдельную статью тянет :)
А насчёт паузы я писал отдельно, но могу еще уточнить: чтобы понять, сколько раз выполняется функция, выполните следующий код:
Смысл в том, что смотрится, сколько раз за одну секунду запустится функция с использованием таймаута. Это значение значение будет скорее всего с дробной частью (которая возникает из-за того, что было отдано недостаточно процессорного времени браузеру), которую нужно будет округлить вниз (floor). Вы сможете убедиться в этом, когда проведёте тест несколько раз: все значения будут меньше либо равны некоторому числу, если на которое разделить 1000 мс из теста, то получится число, очень близкое к целому. Если вы не поняли вышесказанного, то на примере разберётесь.
Пример: у меня Firefox показал 246 раз, Chrome 16 — 197 раз, IE9 — 247 раз, Opera12.0a — 99.
Если разделить 1000 на полученное количество раз, то получим актуальный интервал.
1000 мс/246≈4 мс — для Firefox
1000 мс/197≈5 мс — для Chrome (видимо, минимальный интервал чуть повысили)
1000 мс/247≈4 мс — для IE9 (прошлый тест проводился на восьмой версии)
1000 мс/99≈10 мс — для Opera12.0a
Тесты будут достоверными, если кроме браузера больше никакая программа не будет грузить процессор.