Производительность функции jQuery grep(...) VS native JavaScript filter (...)

я измерил время выполнения этих двух функций:

  • jQuery функции
  • Родной JavaScript фильтр функции

выполнение следующих методов были измерены с помощью инструмента Chrome Profiles:

// jQuery GREP function
function alternative1(words, wordToTest) {
  return $.grep(words, function(word) {
    return wordToTest.indexOf(word) != -1;                    
  });
}

// Native javascript FILTER function        
function alternative2(words, wordToTest) {
  return words.filter(function(word) {
    return wordToTest.indexOf(word) != -1;                    
  });
}

массив words был построен из 1 миллиона случайно сгенерированных строк. Каждый метод был запущен 20 раз. На мой сюрприз jQuery функция grep была быстрее.

время выполнения (20 казней):

  • jQuery функции 26,31 s
  • Родной JavaScript фильтр функции 34,66 s

вы можете повторить измерения по этой jsFidle - это займет некоторое время, чтобы выполнить так что будьте терпеливы.

есть ли объяснение, почему jQuery функция быстрее, чем уроженца JavaScript фильтр?

PS: эти вопросы были вдохновлены этим ответ.

1 ответов


путем сравнения фактической функции jQuery $.grep на странице

function (a, b, c) {
    var d = [],
        e;
    c = !! c;
    for (var f = 0, g = a.length; f < g; f++) e = !! b(a[f], f), c !== e && d.push(a[f]);
    return d
}

(Регистрация здесь для non-minified, спасибо Александр) в отношении алгоритм указал на

Array.prototype.filter.

мне кажется .filter заставляет this to объект проверяет обратный вызов IsCallable и телеаппаратуры this в нем, а также проверка наличия свойства в каждом итерация, тогда как .grep предполагает и пропускает эти шаги, что означает, что происходит немного меньше.

объедините это с тем, насколько хорош компилятор JavaScript в Chrome, и вы можете найти разницу в скорости.

добавление некоторых из них в $.grep будет выглядеть как

function (elems, callback, inv, thisArg) {
    var ret = [],
        retVal;
    inv = !!inv;
    for (var i = 0, length = elems.length; i < length; i++) {
        if (i in elems) { // check existance
            retVal = !!callback.call(thisArg, elems[i], i); // set callback this
            if (inv !== retVal) {
                ret.push(elems[i]);
            }
        }
    }
    return ret;
}

и занять примерно столько же времени, сколько .filter (модифицированный jsperf Александра).