Какой способ поиска дубликатов быстрее?
Давайте еще раз посмотрим как убрать дубликаты в массиве с помощью нашего любимого JavaScript. Да, тема изъезжена десять раз. Но… вы когда нибудь смотрели как быстро работает тот или иной способ? А на большом количестве данных? Эта статья как раз и посвящена данному вопросу.
Начнем с хорошо знакомого filter. У нас есть исходный массив:
Способ первый, воспользуемся для начала filter, и отфильтруем наш массив:
Как видим, это прекрасно работает и дает нужный результат, но есть еще несколько способов сделать подобное. Например, воспользоваться таким отличным инструментом, как reduce, он отлично работает при сложных операциях над массивом, здесь мы его применим в наших целях вот так:
Согласитесь, выглядит не плохо.
И наконец более современный способ с привлечением нового типа в JavaScript — Set, который значительно уменьшает количество кода:
Это наверное один из самых коротких способов по количеству кода.Больше интересного у меня на канале.
А что, если взять старый добрый цикл for и применить его:
Согласен, количество кода не радует, но цель посмотреть, что сейчас наиболее эффективно работает, эксперимент — есть эксперимент.
Для тестирования я возьму последнюю версию Chrome, на момент написания — это 74.0.37 и будем тестировать на MacBook Pro. Код для тестирования можно посмотреть здесь.
Для эксперимента созданы несколько массивов, длинной 100, 500, 1000 и 5000 элементов. По сути — это цифры по возрастанию и каждый десятый элемент заменен на строку ‘string’, которую нам нужно и убрать.
Затем, поочередно запускаем вышеперечисленные функции. Для чистоты эксперимента делаем это 5000 раз и с помощью window.performance.now() высчитываем время выполнения операции.
Итак, что у нас получается.
Для массива в 100 элементов, среднее(максимальное) выполнение:
filter — 0,011(0,325)ms
reduce — 0,02(0,4)ms
set — 0,005(0,275)ms
for — 0,009(1,185)ms
Теперь для массива в 500 элементов:
filter — 0.146(0.475)ms
reduce — 0,385(0.865)ms
set — 0,019(0.35)ms
for — 0.148(0.465)ms
Ну и наконец для 5000, чтобы проверить на достаточно приличном количестве данных. Это занимает какое-то время и машина немного задумывается на данном моменте, но результат такой:
filter — 13.747(18.550)ms
reduce — 32,325(86.790)ms
set — 0,253(0.915)ms
for — 18.880(12.483)ms
Что же, результаты и распределение победителей не сильно отличается при увеличении нагрузки. Как мы видим reduce в данном случае в разы проигрывает старому доброму for и filter и в сотню раз медленнее Set. Однозначно можно исключить его при фильтрации дубликатов.
Итого
Победителем однозначно можно считать Set, он на порядок быстрее справляется с задачей в сравнении с другими способами, плюсом такой способ еще и быстрее писать.
Вторым эффективным способом остается filter, который отлично справляется задачей и делает это за вполне приемлемое время. Не сильно отстает от него и for, хотя изначально в него слабо верилось.
Если понравилась история, то подпишись на мой Телеграм канал