Более эффективный метод сортировки jQuery для элементов DOM на основе числового атрибута - PullRequest
9 голосов
/ 21 декабря 2010

У меня есть несколько простых jQuery, написанных для сортировки некоторых элементов на основе числового атрибута, как показано на http://jsfiddle.net/MikeGrace/Vgavb/

// get array of elements
var myArray = $("#original div");

// sort based on timestamp attribute
myArray.sort(function (a, b) {

    // convert to integers from strings
    a = parseInt($(a).attr("timestamp"), 10);
    b = parseInt($(b).attr("timestamp"), 10);

    // compare
    if(a > b) {
        return 1;
    } else if(a < b) {
        return -1;
    } else {
        return 0;
    }
});

// put sorted results back on page
$("#results").append(myArray);

Он работает нормально, но я не думаю, что он будет масштабироваться, потому что в общей сложности сделано 185 вызовов jQuery, 184 из которых получают атрибут элемента для сравнения.

Какой способ сортировки с помощью jQuery более эффективен?

Ответы [ 5 ]

6 голосов
/ 21 декабря 2010

Если вы беспокоитесь о производительности и точно знаете, откуда берется атрибут, вы можете напрямую использовать методы DOM, .getAttribute() в этом случае:

a = parseInt(a.getAttribute("timestamp"), 10);
b = parseInt(b.getAttribute("timestamp"), 10);

Вы можете проверить разницу здесь , так как вы видите, что это больше, чем небольшое увеличение скорости, .attr() выполняет лот дополнительной работы внутри, в конечном счете вызывая.getAttribute() сам в этом случае в любом случае.

4 голосов
/ 21 декабря 2010

Если вам нужно многократно выполнять сортировку, было бы неплохо поработать над более нативным подходом, не включающим jQuery.В противном случае, на самом деле мало что изменится.

Вот несколько тестов, в которых используется несколько разных подходов -> http://jsperf.com/jquery-sort-by-numerical-property/2

3 голосов
/ 23 августа 2013

Использование jQuery 1.6. Данные () будут намного быстрее.

Первое:

Атрибуты данных извлекаются при первом обращении к свойству данных.доступ к нему, а затем к нему больше нет доступа или изменения (все значения данных затем сохраняются внутри в jQuery).

Это означает доступ к определенному значению данных после того, как первое является внутренним, поэтому поиск DOM или анализ не выполняется.значение должно быть сделано.

Секунда:

Каждая попытка конвертировать строку в значение JavaScript (это включает логические значения, числа, объекты, массивы и ноль),Строковое значение «100» преобразуется в число 100.

Теперь, когда значение хранится внутри как число, его также не нужно анализировать каждый раз.

Html

<div id="original">
  <div data-timestamp="99">99</div>
  <div data-timestamp="999">999</div>
  <div data-timestamp="12">12</div>
  <div data-timestamp="11">11</div>
  <div data-timestamp="10">10</div>
  <div data-timestamp="9">9</div>
  <div data-timestamp="8">8</div>
  <div data-timestamp="7">7</div>
  <div data-timestamp="6">6</div>
  <div data-timestamp="5">5</div>
  <div data-timestamp="4">4</div>
  <div data-timestamp="3">3</div>
  <div data-timestamp="2">2</div>
  <div data-timestamp="1">1</div>
  <div data-timestamp="9999">9999</div>
</div>

Javascript

// sort based on timestamp attribute
myArray.sort(function (a, b) {

    // convert to integers from strings
    a = $(a).data("timestamp");
    b = $(b).data("timestamp");
    count += 2;
    // compare
    if(a > b) {
        return 1;
    } else if(a < b) {
        return -1;
    } else {
        return 0;
    }
});

Обновить пример jsFiddle

Уверены, что ваши циклы одинаковы, но гораздо меньше обработки в цикле.

2 голосов
/ 21 декабря 2010

Для чего бы это ни стоило, я не думаю, что вам нужно вызывать медленный parseInt:

a = parseInt($(a).attr("timestamp"), 10);
a = +$(a).attr("timestamp");

Если ваш атрибут отметки времени на самом деле является просто числом, я думаю, что он даст то же значение.

1 голос
/ 18 мая 2013

Если ваша функция сравнения дорогая, стандартным методом является преобразование Шварца (замечено в некоторых комментариях, но без реального примера):

  1. извлекает ключи сортировки в пары [ключ, объект]
  2. сортировка с использованием извлеченных ключей
  3. извлечение исходных объектов

Пример:

Array.prototype.schwartzian_sort = function (key_of) {
   var i;

   for (i = 0; i < this.length; ++i)
      this[i] = [key_of (this[i]), this[i]];

   this.sort (function (a, b) {
      a = a[0];
      b = b[0];

      return a < b ? -1
           : a > b ?  1
           :          0;
   });

   for (i = 0; i < this.length; ++i)
      this[i] = this[i][1];

   return this;
}

Вместо функции сравнения вы передаетефункция, которая извлекает строки или числа:

myArray.sort(function (e) {
   return parseInt ($(a).attr ("timestamp"), 10);
});

Вызывает parseInt и attr только один раз для каждого элемента, что всегда меньше, чем при вызове в функции сравнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...