Comments 51
Ещё можно было оценить производительность конструкции with(...) { } — было бы интересно.
0
получилось где-то в 2 раза:
IE 6: 6203 / 3250
IE 7: 7765 / 3766
Firefox 2: 10984 / 5204
Safari 3: 796 / 344
Opera 9.5: 1875 / 1078
var start = new Date();
var f = a.b.c.d;
for (var i = 0; i < 1000000; i++) {
with(v){f(this)}
}
var now = new Date();
document.write("<p>Difference: " + (now - start) + "</p>");
start = new Date();
for (var i = 0; i < 1000000; i++) {
f(v);
}
now = new Date();
document.write("<p>Difference: " + (now - start) + "</p>");
IE 6: 6203 / 3250
IE 7: 7765 / 3766
Firefox 2: 10984 / 5204
Safari 3: 796 / 344
Opera 9.5: 1875 / 1078
+1
Итак, выигрыш в 29% действительно впечатляет, но он дает всего лишь 0,7 микросекунды на итерацию, что не стоит того, чтобы это оптимизировать.
А если бы выигрыш был в 5 раз, то всё равно это было бы только около 10 мкс. Тоже не стоит оптимизировать?
0
Если уж на то пошло, то на каждой итерации цикла тратится время не только на разрешение имени в объект-функцию, но и её вызов (со всем многоэтапным созданием исполнительного контекста).
Так что разница между разрешением f и a.b.c.d далеко не 29%.
Ну и оба случая не идентичны, так как в первом случае вызов идет в контексте a.b.c, а во втором в контексте window :-D
Так что разница между разрешением f и a.b.c.d далеко не 29%.
Ну и оба случая не идентичны, так как в первом случае вызов идет в контексте a.b.c, а во втором в контексте window :-D
+1
не совсем. В первом случае window.a.b.c
для анонимной функции все работает побыстрее, соотношения сохраняются, в принципе. IE, однако, чуток замедляется, для второго варианта сильнее.
для анонимной функции все работает побыстрее, соотношения сохраняются, в принципе. IE, однако, чуток замедляется, для второго варианта сильнее.
0
>для анонимной функции все работает побыстрее
Хорошо, что Вы вспомнили про функции. Ведь, как правило, именно в функциях, а не в глобальной области, выполняется подавляющее количество операций.
Так вот, если тестировать подобное в функциях, то результаты могут оказаться прямо противоположными, и вся эта оптимизация получит знак "минус". Вот здесь можно взглянуть на подобный тест, но с совершенно другими результатами (проявите максимум внимания - там мужчина проделал отличную работу).
Кстати, то, что Вы обращаетесь за материалом "за бугор", не используя "родной", выглядит немного странно. ;)
Хорошо, что Вы вспомнили про функции. Ведь, как правило, именно в функциях, а не в глобальной области, выполняется подавляющее количество операций.
Так вот, если тестировать подобное в функциях, то результаты могут оказаться прямо противоположными, и вся эта оптимизация получит знак "минус". Вот здесь можно взглянуть на подобный тест, но с совершенно другими результатами (проявите максимум внимания - там мужчина проделал отличную работу).
Кстати, то, что Вы обращаетесь за материалом "за бугор", не используя "родной", выглядит немного странно. ;)
+2
да, в сообщениях предложен более оптимальный вариант:
for (var i = 0, e = a.b.c.d; i < 10000; i++) {
e.e();
}
0
Я, конечно, в первую очередь хотел подчеркнуть, что f(v) далеко не всегда быстрее a.b.c.d(v). Но оптимальный вариант, на который Вы обратили внимание, естественно, заслуживает того. Хотя все это упирается в зависимости, которые угадать, как мне кажется, довольно сложно. Это может быть и сам движок, выполняющий js-программу, и окружение, в котором происходит вызов, и т.д. Следовательно, делать выводы об оптимизации в такой нестабильной среде надо очень осторожно.
0
Осталось только обосновать/объяснить, откуда в этом случае вылезает оптимизация.
0
>откуда в этом случае вылезает оптимизация.
Это Вы про dklab-оптимизацию? Или про какую?
Я для себя давно эти варианты разобрал (и даже, кажется, понял - во как!), но очень хотелось бы обсудить в деталях.
Это Вы про dklab-оптимизацию? Или про какую?
Я для себя давно эти варианты разобрал (и даже, кажется, понял - во как!), но очень хотелось бы обсудить в деталях.
0
e() vs. e.e()
0
Я решил, что суть в следующем. Когда функция в качестве this value получает в свое распоряжение null (это именно тот случай, когда функция вызывается, как e(), и base object => activation object), то появляются дополнительные расходы на подстановку global вместо этого null. Под "дополнительными расходами" я подразумеваю то, что у них (во всяких monkeys) неоптимизирован алгоритм именно получения значения global, т.е. используется какая-нибудь медленная функция, типа js_ComputeGlobalThis. И это настолько "медленно", что в результате "съедается" вся оптимизация (избавление от операторов точка).
+3
Знал бы симанку, мож чё умное и выдал бы. Звучит версия логично. Напишите в http://groups.google.com/group/netscape.… , интересно же. Я-то подозревал, что в каком-то месте работает оптимизация lookup-ов или где-то что-то кешируется (допустим, последнее значение), а в отношении неполного имени 'e' этого не происходит. Сейчас вижу, что медленнее именно вызовы и именно из-под функции... причуды движка, разрушающие js-мировоззрение. ;)
0
Я обратился в другую группу - comp.lang.javascript. В ней, как-будто, активность больше, соответственно и шансов больше (если поймут мой "ломаный"). Правильно сделал? Или в netscape.public.mozilla тоже написать?
0
В c.l.j если ответят, то не по существу, всё-таки вопрос касается внутренних алгоритмов, это ближе знатокам движка...
0
Даже если dot-ов в имени много такой вызов всё равно в FF быстрее, чем unqualified name, пример - http://www.404.googlepages.com/test_ff_s…
0
>в каком-то месте работает оптимизация lookup-ов или где-то что-то кешируется (допустим, последнее значение)
Понаблюдал еще немножко, и вот что заметил. При сохранении значения ссылки на функцию в локальной переменной не видно различий в длине цепи property accessors (т.е. f = a.b.c и f = a.b.c.d.e.f.g.h – к счастью как-будто одинаково, как и должно быть). А вот вызов метода будет занимать разное время, которое варьируется от кол-ва "точек". В IE на "точки" уходит больше времени, чем в FF – в результате "точек" пять-шесть (к примеру) уравняют время исполнения (f() и a.b.c.d.e()). В FF "точки" "быстры" – чтобы время выполнения было одинаковым, нужно для пути к методу использовать весь алфавит. Вот тут и задумаешься – есть ли оптимизация lookup-ов? Вообще, если по уму, то быть обязана, но, как мне показалось (или может так оно и есть), больше "точек" – больше времени, и это сбивает с толку (т.е. где она, оптимизация?)...
Все же для того, чтобы сделать выводы нужно еще какие-нибудь тесты придумать. Пока в голове пусто...
Понаблюдал еще немножко, и вот что заметил. При сохранении значения ссылки на функцию в локальной переменной не видно различий в длине цепи property accessors (т.е. f = a.b.c и f = a.b.c.d.e.f.g.h – к счастью как-будто одинаково, как и должно быть). А вот вызов метода будет занимать разное время, которое варьируется от кол-ва "точек". В IE на "точки" уходит больше времени, чем в FF – в результате "точек" пять-шесть (к примеру) уравняют время исполнения (f() и a.b.c.d.e()). В FF "точки" "быстры" – чтобы время выполнения было одинаковым, нужно для пути к методу использовать весь алфавит. Вот тут и задумаешься – есть ли оптимизация lookup-ов? Вообще, если по уму, то быть обязана, но, как мне показалось (или может так оно и есть), больше "точек" – больше времени, и это сбивает с толку (т.е. где она, оптимизация?)...
Все же для того, чтобы сделать выводы нужно еще какие-нибудь тесты придумать. Пока в голове пусто...
0
>в первом случае вызов идет в контексте a.b.c, а во втором в контексте window
Судя по всему, оба вызова функции происходят в глобальном контексте. Разница в том, чьим методом является анонимная функция (function(arg) { return arg; }) в момент вызова.
Судя по всему, оба вызова функции происходят в глобальном контексте. Разница в том, чьим методом является анонимная функция (function(arg) { return arg; }) в момент вызова.
0
gro говорит о "вызове в контексте" конкретных объектов (то бишь, какое значение будет у this в зависимости от записи вызова), придирка ваша зряшная. ;) Примеры этого не учитывают, как писали 5 лет назад, так и сейчас копипастят в том же виде, без оглядки на this вообще...
+1
еще память измерьте :)
0
> 1 миллион итераций в 2374 миллисекунды или 2,4 микросекунды на итерацию для первого случая
2374 миллисекунды = 2.374 секунды
1с = 1000мс = 1000000мкс
http://ru.wikipedia.org/wiki/Приставки_СИ
исправьте!
2374 миллисекунды = 2.374 секунды
1с = 1000мс = 1000000мкс
http://ru.wikipedia.org/wiki/Приставки_СИ
исправьте!
+2
что править-то? что миллион итераций на 2,4 микросекунды будет 2374 миллисекунды? :)
0
исправить то, что написано автором и выделено мной.
2000 миллисекунды не могут равняться 2 микросекундам.
я уже сказал, чему это равно.
2000 миллисекунды не могут равняться 2 микросекундам.
я уже сказал, чему это равно.
0
возвращаясь к сказанному.
это ж надо было так построить фразу, чтобы скрыть явный смысл.
проще было бы поделить в коде на те пресловутые миллион итераций и вывести "мкс" в тексте.
это ж надо было так построить фразу, чтобы скрыть явный смысл.
проще было бы поделить в коде на те пресловутые миллион итераций и вывести "мкс" в тексте.
+1
95% ресурсов в JavaScript отъедает работа с DOM объектами: изменение стилей и иерархии DOM терева. Оставшиеся 5% - это непосредственные вычислительные тормоза JavaScript.
Поэтому, даже если вы получили 23% прироста в вычислительной части, то домножьте эти 23% на те 5% которые вычислительная часть занимает в сайте. Получится чуть более 1% реального прироста производительности.
Поэтому, даже если вы получили 23% прироста в вычислительной части, то домножьте эти 23% на те 5% которые вычислительная часть занимает в сайте. Получится чуть более 1% реального прироста производительности.
+2
вот разница в использовании innerHTML VS doc.createElement...node.appendChild действительно большая.
я бы сказал, что оптимизировать надо там, где профайлер показывает "плохое" время и не заморачиваться над экономией "на спичках", пока есть чем заниматься кроме этого.
я бы сказал, что оптимизировать надо там, где профайлер показывает "плохое" время и не заморачиваться над экономией "на спичках", пока есть чем заниматься кроме этого.
+1
Уважаемый, а где время все-таки больше в innerHTML или createElement? Сам, интуитивно использую последний вариант, но мало ли что... а до эксперемента пока руки не доходят:)
0
innerHTML быстрее createElement, а cloneNode самый быстрый способ если вам нужно получить множество одинаковых узлов.
0
вот тут хорошая статья про общую производительность JS/AJAX
http://webo.in/articles/habrahabr/23-hig…
http://webo.in/articles/habrahabr/23-hig…
+1
Имхо, ваш метод тестирования не оптимален. Не стоит говорить и конкретном проценте (29%) или описывайте более продробно условия теста. Сколько раз вы прогоняли тест? Сотни раз, тысячи? Ваша ОС?
Ради интереса прогнал в 4х браузерах по 10-15 раз. Результат: разброс от -10% до 45% на каждый прогон (как и следовало ожидать). Т.е. надо прогонять тест тысячи раз на _разных_ машинах и брать среднее значение.
А в общем статься полезна, спасибо ^___^
Ради интереса прогнал в 4х браузерах по 10-15 раз. Результат: разброс от -10% до 45% на каждый прогон (как и следовало ожидать). Т.е. надо прогонять тест тысячи раз на _разных_ машинах и брать среднее значение.
А в общем статься полезна, спасибо ^___^
0
Попробуйте на цепочках jQuery потестировать.
0
Отлично! Хотя проблем с производительностью не возникало с цепочками и подлиннее чем в примерах, всё-равно буду иметь ввиду.
0
На самом деле, тут не прирост производительности на 29%.
Тут лучше с другой стороны посмореть. А с другой стороны у нас падение производительности почти на 50% относительно "оптимизированного" кода.
Тут лучше с другой стороны посмореть. А с другой стороны у нас падение производительности почти на 50% относительно "оптимизированного" кода.
0
Проверил у себя на компьютере:
Проценты может быть другие, но тенденция налицо.
IE 6.0 : 5782 / 5094
IE 8.0 beta : 3835 / 2864
Firefox 2.0.0.1 : 1875 / 1547
Opera 9.0 : 2203 / 2047
Safari 3.0.3 : 2172 / 1906
Проценты может быть другие, но тенденция налицо.
0
ха ха
напишите вот так
сильно удивитесь (-:
(function(){
var f = a.b.c.d;
for (var i = 0; i < 1000000; i++) {
f(v);
}
})();
напишите вот так
сильно удивитесь (-:
(function(){
var f = a.b.c.d;
for (var i = 0; i < 1000000; i++) {
f(v);
}
})();
0
>Sree Kotay
Интересные имя и фамилия...
Интересные имя и фамилия...
0
Я, конечно, извиняюсь, но какой может быть байткод (и тем более JIT-компиляция) в JavaScript?
0
>... какой может быть байткод (и тем более JIT-компиляция) в JavaScript?
Brendan Eich:
Brendan Eich:
For Mozilla 2, we will have a JIT-oriented JavaScript VM...
0
"JScript Classic acts like a compiled language in the sense that before any JScript Classic program runs, we fully syntax check the code, generate a full parse tree, and generate a bytecode. We then run the bytecode through a bytecode interpreter. In that sense, JScript is every bit as "compiled" as Java. The difference is that JScript does not allow you to persist or examine our proprietary bytecode. Also, the bytecode is much higher-level than the JVM bytecode the JScript Classic bytecode language is little more than a linearization of the parse tree, whereas the JVM bytecode is clearly intended to operate on a low-level stack machine."
--Eric Lippert-- (JScript)
"Client JavaScript reads source from SCRIPT tag contents, but compiles it into an internal bytecode for faster interpretation."
--Brendan Eich-- (JavaScript)
--Eric Lippert-- (JScript)
"Client JavaScript reads source from SCRIPT tag contents, but compiles it into an internal bytecode for faster interpretation."
--Brendan Eich-- (JavaScript)
+2
Sign up to leave a comment.
Оптимизируем JavaScript: насколько ресурсоемки цепочки вызовов?