Действительно ли reduce, filter, map и прочие работают медленнее обычного for?
Добрый день. Решил поглубже погрузиться в изучение операций с массивами, пробуя решать одни и те же задачи разными способами и измеряя производительность старым добрым performance.now(). И с удивлением обнаружил, что в подавляющем большинстве задач вышеупомянутые reduce, filter, map, find отрабатывают медленнее (иногда даже в десятки раз), чем более многословный и многоэтажный цикл for. Задачи самые разные - сортировка, математические операции с элементами массива, фильтрация по самым разным критериям и проч. И почти всегда for работает быстрее. Также, что интересно - иногда в небольших массивах for работает медленнее. Но если массив большой, скажем, от 1000 элементов - то for вырывается вперед. Это действительно так, или все-таки есть некий ограниченный круг задач, где означенные методы выигрывают в производительности? Тогда хотелось бы знать, какого рода могут быть эти задачи.
"Решил поглубже погрузиться в изучение операций", почитайте пожалуйста самостоятельно как они написаны.
может ли for быть быстрее самого себя, но с дополнительными проверками?
Ice, ну ещё не забываем про то что вызывается колбэк, вместо кода тела и ещё то что происходит постоянное копирования массивов. Если ещё и по цепочке это происходит - ещё хуже. Ещё всякие оптимизации от JIT-компилятора могут лучше ложиться на обычный код
Сегодня быстрее, завтра не быстрее, послезавтра быстрее.
Перфоманс таких вещей зависит от реализации js и будет разным на разных движках и версиях.
Без веских причин не стоит экономить на спичках жертвуя читабельностью.
Будь методы перебора массивов не нужны, их не сделали бы, правда ведь?
Функциональный подход - не всегда синоним читабельности. И тем более не синоним понимабельности.
Если заменить один простой for на один простой forEach или map - это действительно смотрится чище.
Но бывает и так (лично видел, в том числе на тостере), что кодеры с функциональщиной головного мозга строят цепочку из 3-5 мапов и фильтров там, где то же самое можно было сделать одним циклом буквально с одним if-ом внутри. Потому что эти колбеки не знают друг о друге и могут работать только последовательно.
Короче, всегда привлекайте здравый смысл.
dom1n1k,
там, где то же самое можно было сделать одним редьюсом
fixed
Если честно еще не видел ситуаций, где for сделал бы что-то проще. Обычно все нормально пишется через функции перебора массива и тестировать удобнее.
И это не совсем то, что принято понимать под функциональным подходом.
for-of нужен чтобы перебирать iterable с возможностью досрочного выхода.
This change affects a bunch of other builtins like Function.prototype.apply, Reflect.apply, and many higher-order array builtins (e.g. Array.prototype.map).
Вот reduce я точно не люблю.
За исключением элементарных случаев, они часто сложны для понимания. Элементарный случай это когда редьюсер возвращает одно значение - ну например сумму по массиву посчитали.
Но бывает что городят сложные преобразования массивов, с пушами/конкатами/слайсами/джойнами и тд. Сидишь и силишься понять, что куда втекает-вытекает и где что по дороге потерялось.
Всё из-за постоянных проверок типов данных.
Хотите быстро - нативный js
Хотите очень быстро - c++ либы через emscripten. Ну, и не кривые алгоритмы, разумеется.
Ну а чо тут удивительного? Как бэ это очевидно. Ну на маленьких массивах это не заметно и смысла нет запариваться, если массив большой, то разница всегда очень приличная. Да и сортировка встроенная в js не всегда самая быстрая и т.д. В любом случае львиная доля js разрабов с такими задачами врядли столкнется. Да и зачем в этом разбираться, алгоритмы жеж для лохов.
Да, действительно все эти методы работают медленнее обычного for.
Безусловно медленнее и так будет всегда. Никакой прогресс JS-компиляторов не изменит этой ситуации. Оптимизации компиляторов могут только уменьшать отставание данных методов от простого цикла, но никогда не сделает их равными и уж тем более быстрее. Преимущество этих методов не в скорости, а исключительно в читаемости кода и то при условии разумного применения.
Но всегда нужно смотреть по ситуации. Может у вас массив из 10 элементов и ваша потенциальная экономия это 1 микросекунда? В большинстве случаев (хотя и не всегда) проигрыш производительности будет пренебрежимо мал.
Но если вы обоснованно считаете, что перфоманс вам критически важен - конечно, используйте for.