jQuery profiling

С тех пор как как я написал про то как ускорить селекторы в jQuery меня все беспокоит скорость работы разных частей библиотеки. 21 февраля я проводил тестирование производительности селекторов, а 23 примерно таким же профайлингом занимался John в статье JavaScript Function Call Profiling. Я тогда еще подумал что все что я сделал можно выкинуть, потому что он написал лучше и подробнее.

Но он затронул далеко не все методы, а только основные. Именно этим я сейчас и собираюсь заняться, я собираюсь пройтись по всей документации выписать методы и посмотреть какие методы и сколько времени работают. В общем работа не сложная но нудная. Скрипт замеров уже есть плюс FireUnit мне поможет. Записывать буду имя тестируемого метода, количество вызовов внутри него, соотношение количества внутренних вызовов к количеству выбранных элементов (O), среднее время. Если O меньше 2n, то оно не записывается и считается примерно равным одному n , а n == 40, потому что в примере участвует 40 дивов. Для примера была взята страницы выдачи результатов Google и чуть-чуть подправлена. Да и еще есть такие методы которые работаю только с первым элементом коллекции, в основном получают значение его параметров, для них вноситься отдельная правка.

Пример отрабатывает долго поэтому я вынес его в отдельный файл, смотрите чтоб не подвесил ваш браузер. Хотел сделать еще сравнение по версиям типа 1.3.2 vs 1.2.6 но последний даже не смог полностью отработать — виснет, поэтому предлагаю тем кому действительно интересно сохранить страницу поправить версию и запустить локально, закомментировав половину кода. И там еще какие-то глюки с replaceAll, вроде как из-за него виснет. Но могу сказать заранее, что хоть в более новой версии показатель О выше (больше вызовов функций на каждый элемент), но работает она в среднем быстрее.

И последние перед тем как я дам ссылку на пример его нужно смотреть в FireFox c установленным FireBug и FireUnit. UPD Тут была ссылка на пример, но так как FireUnit не зарелизился даже на первой версии, и уже давно перестал работать, то я ее убрал.

Для тех кто по каким-то религиозным причинам не хочет ставить себе всё это публикую результат теста проведенного на моей машине.

Attributes/Attr

divs.attr(«align»); 6 O(6n) 0.075
divs.attr({align: «center»}); 284 O(7n) 2.381
divs.attr(«align», «center»); 284 O(7n) 2.627
divs.attr(«align», function () {}); 324 O(8n) 2.089
divs.removeAttr(«align»); 204 O(5n) 2.29

Attributes/Class

divs.addClass(«test»); 223 O(6n) 1.706
divs.addClass(«test»); 244 O(6n) 1.255
divs.hasClass(«test»); 11 0.286
divs.removeClass(«test»); 304 O(8n) 2.188
divs.removeClass(«test»); 247 O(6n) 1.795
divs.toggleClass(«test»); 303 O(8n) 2.271
divs.toggleClass(«test»); 384 O(10n) 2.739
divs.toggleClass(«test», true); 223 O(6n) 1.792
divs.toggleClass(«test», true); 244 O(6n) 1.277
divs.toggleClass(«test», false); 247 O(6n) 1.81
divs.toggleClass(«test», false); 304 O(8n) 2.26

Attributes/HTML

divs.html(); 2 O(2n) 2.221
divs.html(«<p>test</p>»); 9907 O(6n+n2) 71.238

Attributes/Text

divs.text(); 6500 O(4n+n2) 35.785
divs.text(«test»); 9902 O(6n+n2) 71.749

Attributes/Value

divs.val(); 4 O(4n) 0.04
divs.val(«myValue»); 124 O(3n) 1.046
divs.val([«myValue»]); 124 O(3n) 1.082

Traversing/Filtering

divs.eq(0); 9 0.05
divs.hasClass(«test»); 11 0.25
divs.filter(«div»); 100 O(3n) 0.606
divs.filter(function () {}); 90 O(2n) 0.248
divs.is(«div»); 52 0.345
divs.is(«.test»); 10 0.228
divs.map(function () {}); 89 O(2n) 0.24
divs.not(«div»); 104 O(3n) 0.651
divs.not(«.test»); 20 0.329
divs.slice(0, 1); 8 0.048

Traversing/Finding

divs.add(«span»); 106 O(3n) 1.369
divs.children(«span»); 216 O(5n) 3.238
divs.closest(«div»); 690 O(17n) 5.565
divs.closest(«span»); 4612 O(3n+n2) 38.784
divs.contents(); 316 O(8n) 3.952
divs.find(«span»); 462 O(12n) 5.147
divs.next(«span»); 121 O(3n) 1.145
divs.nextAll(«span»); 161 O(4n) 1.761
divs.offsetParent(«span»); 4 O(4n) 0.311
divs.parent(«span»); 100 O(3n) 0.746
divs.parents(«span»); 383 O(10n) 3.348
divs.prev(«span»); 136 O(3n) 1.445
divs.prevAll(«span»); 190 O(5n) 2.478
divs.siblings(«span»); 251 O(6n) 3.403

Traversing/Changing

divs.andSelf(); 55 0.425
divs.end(); 2 0.006

Manipulation/Changing Contents

divs.html(); 2 O(2n) 2.196
divs.html(«<p>test</p>»); 9907 O(6n+n2) 72.032
divs.text(); 6500 O(4n+n2) 36.241
divs.text(«test»); 9902 O(6n+n2) 71.661

Manipulation/Inserting Inside

divs.append(«<p>test</p>»); 133 O(3n) 1.675
divs.appendTo(«#form»); 176 O(4n) 3.429
divs.appendTo(«form»); 191 O(5n) 3.506
divs.appendTo(«.form»); 192 O(5n) 3.534
divs.appendTo(«<form/>»); 184 O(5n) 3.149
divs.prepend(«<p>test</p>»); 133 O(3n) 2.155
divs.prependTo(«form»); 191 O(5n) 3.509

Manipulation/Inserting Outside

divs.after(«form»); 91 O(2n) 1.903
divs.after(«<form/>»); 94 O(2n) 2.078
divs.before(«form»); 91 O(2n) 1.457
divs.before(«<form/>»); 94 O(2n) 1.611
divs.insertAfter(«form»); 190 O(5n) 3.553
divs.insertBefore(«form»); 190 O(5n) 3.528

Manipulation/Inserting Around

divs.wrap(«<span/>»); 2644 O(2n+n2) 22.655
divs.wrap(document.createElement(«span»)); 2524 O(2n+n2) 20.983
divs.wrapAll(«<span/>»); 181 O(5n) 7.886
divs.wrapAll(document.createElement(«span»)); 178 O(4n) 7.85
divs.wrapInner(«<span/>»); 3245 O(2n+n2) 31.313
divs.wrapInner(document.createElement(«span»)); 3140 O(2n+n2) 29.689

Manipulation/Replacing

divs.replaceWith(«<span/>»); 7636 O(5n+n2) 60.003
divs.replaceAll(«span»); 35 1.854

Manipulation/Removing

divs.empty(); 9774 O(6n+n2) 72.261
divs.remove(); 6982 O(4n+n2) 55.583

Manipulation/Copying

divs.clone(); 90 O(2n) 3.304
divs.clone(true); 5309 O(3n+n2) 52.121

CSS/CSS

divs.css(«color»); 4 O(4n) 0.136
divs.css(«color», «red»); 205 O(5n) 2.119
divs.css({color: «red», border: «1px solid red»}); 365 O(9n) 4.112

CSS/Positioning

divs.offset(); 2 O(2n) 0.337
divs.position(); 14 0.51
divs.scrollTop(); 2 O(2n) 0.112
divs.scrollTop(10); 44 0.475
divs.scrollLeft(); 2 O(2n) 0.112
divs.scrollLeft(10); 44 0.468

CSS/Height and Width

divs.height(); 12 O(12n) 24.01
divs.height(10); 206 O(5n) 2.271
divs.width(); 12 O(12n) 10.789
divs.width(10); 206 O(5n) 2.189
divs.innerHeight(); 10 O(10n) 10.782
divs.innerWidth(); 10 O(10n) 10.533
divs.outerHeight(); 5 O(5n) 10.195
divs.outerHeight(true); 10 O(10n) 10.483
divs.outerWidth(); 5 O(5n) 10.216
divs.outerWidth(true); 10 O(10n) 10.342

Effects/Basics

divs.show(); 162 O(4n) 8.007
divs.show(); 253 O(6n) 2.991
divs.hide(); 162 O(4n) 4.168
divs.hide(); 42 0.393
divs.toggle(); 845 O(21n) 23.782
divs.toggle(true); 325 O(8n) 10.757
divs.toggle(false); 325 O(8n) 5.31

Effects/Sliding

divs.slideUp(); 1328 O(33n) 8.703
divs.slideUp(); 3679 O(2n+n2) 101.01
divs.slideDown(); 2280 O(n2) 62.462
divs.slideDown(); 2200 O(n2) 61.412
divs.slideToggle(); 4927 O(3n+n2) 156.157

Effects/Fading

divs.fadeIn(); 1448 O(36n) 22.658
divs.fadeIn(); 1368 O(34n) 21.313
divs.fadeOut(); 1328 O(33n) 9.04
divs.fadeOut(); 1288 O(32n) 15.798
divs.fadeTo(0, 0.5); 1968 O(n2) 17.539

2 Комментарии “jQuery profiling

  1. Хм, очень интересно, но в «Attributes/Class» зачем по два раза повторил?

    >>>
    divs.closest(«div»); 690 O(17n) 5.565
    divs.closest(«span»); 4612 O(3n+n2) 38.784
    <<<

    Это глюк? Меня удивляет «690» и «4612», почему настолько различается?

  2. потому что когда ищется closest проверяется сам элемент. вот в первом случаи он проверился и вернул сам себя, а во втором пошел реально искать ближайший span.

Комментарии закрыты