Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Поиск по массиву объектов (https://javascript.ru/forum/misc/49427-poisk-po-massivu-obektov.html)

kobezzza 14.08.2014 08:27

Цитата:

но цикл всё равно быстрее.)
От VM зависит. В IE11 нет разницы как правило.

***

А по теме: Collection

Работает быстрее итераторов, циклов и всех известных библиотек и со всеми возможными типами данных :)

Pavel M. 14.08.2014 12:55

действительно
попробовал скорость filter и обычного цикла на большом массиве
в Хроме, FF, IE11

у меня цикл быстрее в разы (см. в console)
спасибо Aetae - не знал

var i,
	maxItems = 1e6,
	arr = [],
	needKey = 500137, // где-то в середине
	myArr;

// генерим массив
for (i = 0; i < maxItems; i += 1) {
  arr.push({key: i, label: i + ''});
}

// test filter
console.time('filter');

myArr = arr.filter(function (item) {
  return (item.key === needKey);
});

console.timeEnd('filter');

alert(JSON.stringify(myArr));


// test цикл
myArr = [];

console.time('for');

for (i = 0; i < arr.length; i += 1) {
   if (arr[i].key === needKey) {
	  myArr.push(arr[i]);
	  break;
   }
}

console.timeEnd('for');

alert(JSON.stringify(myArr));

kobezzza 14.08.2014 13:00

Pavel M. никогда не делай бенчмарки через консоль отладчика, т.к. он отключает использование JIT компилятора и результат замеров может значительно отличаться.

ixth 14.08.2014 13:04

Цитата:

Сообщение от Pavel M. (Сообщение 325827)
действительно
попробовал скорость filter и обычного цикла на большом массиве
в Хроме, FF, IE11

у меня цикл быстрее в разы (см. в console)
спасибо Aetae - не знал

Потому что методика тестирования хромает. filter обходит весь массив, for — нет. Можно попробовать так:

var i,
	maxItems = 1e6,
	arr = [],
	needKey = 500137, // где-то в середине
	myArr;

// генерим массив
for (i = 0; i < maxItems; i += 1) {
  arr.push({key: i, label: i + ''});
}

// test filter
console.time('some');

myArr = [];
arr.some(function (item) {
  if (item.key === needKey) {
    myArr = [item];
    return true;
  }
  return false;
});

console.timeEnd('some');

alert(JSON.stringify(myArr));


// test цикл
myArr = [];

console.time('for');

for (i = 0; i < arr.length; i += 1) {
   if (arr[i].key === needKey) {
	  myArr.push(arr[i]);
	  break;
   }
}

console.timeEnd('for');

alert(JSON.stringify(myArr));


some у меня отрабатывает в полтора раза быстрее filter, но все еще в два раза медленнее, чем for:

Цитата:

some: 23.802ms VM1460:24
for: 14.023ms VM1460:41

ixth 14.08.2014 13:07

Цитата:

Сообщение от kobezzza (Сообщение 325828)
Pavel M. никогда не делай бенчмарки через консоль отладчика, т.к. он отключает использование JIT компилятора и результат замеров может значительно отличаться.

Как насчет jsperf? Первое, что нагуглилось: http://jsperf.com/array-some-vs-loop

kobezzza 14.08.2014 13:11

Цитата:

Сообщение от ixth (Сообщение 325833)
Как насчет jsperf? Первое, что нагуглилось: http://jsperf.com/array-some-vs-loop

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

Для тестирования именно скорости итераций лучше самом написать простой тест, как например тут https://github.com/kobezzza/Collecti...ter/benchmarks

Цитата:

some у меня отрабатывает в полтора раза быстрее filter, но все еще в два раза медленнее, чем for:
Я хоть убей не понимаю, зачем костылить в своём коде и делать оптимизации, которые "завтра" с обновлением VM могут стать абсолютно бесполезными (я уже молчу про части, где часть на циклах, а часть итераторах), но при этом делают наш код ужасным. Есть же готовые либы, которые инкапсулируют в себе все все оптимизации и работают супер быстро, но при этом дают простой и удобный интерфейс, и не нужно самому ничего изобретать.

Я уже молчу про то, что нативные интерфейсы алгоритмически убоги и работают только с массивами. Очень частый пример, нужно сделать фильтр, потом мап, а потом взять первые 10 результатов, т.е.

filter().map().slice()


Алгоритмическая сложность просто ужасна, думаю всем это понятно. Гораздо лучше сделать:

map(..., {filter(), slice()})


Т.е. всё в один проход вместо 3-х

ixth 14.08.2014 13:26

Цитата:

Сообщение от kobezzza (Сообщение 325834)
Я хоть убей не понимаю, зачем костылить в своём коде и делать оптимизации, которые "завтра" с обновлением VM могут стать абсолютно бесполезными (я уже молчу про части, где часть на циклах, а часть итераторах), но при этом делают наш код ужасным.

Ну, лично мне вообще все равно, это просто спортивный вопрос: правда ли, что Array extras (или как там правильно) быстрее, чем простой for?

Цитата:

Сообщение от kobezzza (Сообщение 325834)
Гораздо лучше сделать:

map(..., {filter(), slice()})


Т.е. всё в один проход вместо 3-х

Это какая-то новая экма? Потому что я в ней ни в зуб ногой. Что эта запись означает?

kobezzza 14.08.2014 13:36

Цитата:

Это какая-то новая экма? Потому что я в ней ни в зуб ногой. Что эта запись означает?
Это псведокод :)

С использованием либы Collection это будет выглядеть так:

$C(/* тут наш объект для итераций */).map(function () {
    ...
}, {
    filter: function () {
        ...
    },

    from: 100,
    count: 10
});


Цитата:

Ну, лично мне вообще все равно, это просто спортивный вопрос: правда ли, что Array extras (или как там правильно) быстрее, чем простой for?
Это слишком сложный вопрос, т.к. он привязан к примеру и мощности JIT VM, т.е. однозначного ответа нет.

kobezzza 14.08.2014 13:55

Цитата:

kobezzza,
Я бы использовал либу для итераций еслибы было какое-то проседание в скорости работы кода. Мне это не требуется, у меня нет огромных объемов данных и необходимости быстро их итерировать.
Ну у меня просто другой подход. Я всегда юзаю либу и просто не думаю о количестве и типе данных, т.к. оно всегда будет работать быстро :)

tsigel 14.08.2014 14:06

kobezzza,
Ну это потому что ты написал эту либу)))

Я тоже таскаю некоторые свои штуки из проекта в проект)
А подключать либу на 17кб просто чтобы не париться - неохота)
Я и так не парюсь)


Часовой пояс GMT +3, время: 20:39.