Сравнение производительности $("#foo .bar") и $(".bar", "#foo")

Прокрутите вниз для сравнения getById.getByClassName против qSA!


Если бы мы хотели выбрать все элементы класса "bar", которые находятся внутри элемента с идентификатором "foo", мы могли бы написать так:

$( '#foo .bar' )

или так:

$( '.bar', '#foo' )

Конечно, существуют и другие методы достижения этой цели, но в рамках данного вопроса давайте сравним только эти два метода.

Итак, какой из приведенных выше методов работает лучше? (Какой требует меньше времени на выполнение?)

Я написал этот тест производительности:

(function() {
    var i;

    console.time('test1');
    for( i = 0; i < 100; i++ ) {
        $('#question-mini-list .tags');
    }
    console.timeEnd('test1');

    console.time('test2');
    for( i = 0; i < 100; i++ ) {
        $('.tags', '#question-mini-list');
    }
    console.timeEnd('test2');
})();

Вы должны выполнить его из консоли на стартовой странице Stack Overflow. Мои результаты:

Firefox:
test1: ~90ms
test2: ~18ms

Chrome:
test1: ~65ms
test2: ~30ms

Opera:
test1: ~50ms
test2: ~100ms

Итак, в Firefox и Chrome второй метод в несколько раз быстрее - как я и ожидал. Однако в Opera ситуация обратная. Интересно, что здесь происходит?

Не могли бы вы провести тест на своей машине и объяснить, почему Opera работает по-другому?


Обновление

Я написал этот тест, чтобы выяснить, действительно ли qSA в Opera является сверхбыстрым. Как оказалось, это так.

(function() {
    var i, limit = 5000, test1 = 'test1', test2 = 'test2';

    console.time( test1 );
    for( i = 0; i < limit; i += 1 ) {
        document.getElementById( 'question-mini-list' ).getElementsByClassName( 'tags' );
    }
    console.timeEnd( test1 );

    console.time( test2 );
    for( i = 0; i < limit; i += 1 ) {
        document.querySelectorAll( '#question-mini-list .tags' );
    }
    console.timeEnd( test2 );
})();

Опять же, вы должны запустить этот код из консоли на стартовой странице Stack Overflow. Я использовал букмарклет Firebug Lite для IE9 (поскольку этот браузер не реализует console.time).

Итак, я сравнил этот метод:

document.getelementById( 'A' ).getElementsByClassName( 'B' );

с этим методом:

document.querySelectorAll( '#A .B' );

Я выполнил приведенный выше сценарий пять раз подряд в каждом браузере. Арифметические значения:

enter image description here

(Все числа указаны в миллисекундах.)

Итак, производительность первого метода практически одинакова в протестированных браузерах (16-36 мс). Однако, хотя qSA работает намного медленнее, чем первый метод, в Opera он работает быстрее!

Итак, оптимизация qSA возможна, интересно, чего ждут другие браузеры...

9
задан Šime Vidas 22 December 2011 в 05:22
поделиться