Эффективность list.Reverse() в JavaScript?

Кто-нибудь знает, насколько эффективен .reverse() в JS для обращения списка объектов?

Мне любопытно, будет ли какая-либо значительная потеря производительности при сортировке списка (скажем, 100 объектов) в порядке возрастания и в обратном порядке, а не просто сортировка списка в порядке убывания.

Редактировать: Поэтому я провел несколько тестов сортировки массива по убыванию, а затем по возрастанию с обратным. Результаты довольно интересные: (работает в хроме)

  • 1000 элементов в случайном порядке, нормальная сортировка по убыванию, 10000 попыток: 0,3681 мс
  • 1000 элементов в случайном порядке, сортировка по возрастанию, затем в обратном порядке, 10000 попыток: 0,3651 мс
  • 1000 элементов в порядке возрастания, обычная сортировка по убыванию, 10000 попыток: 0,0282 мс
  • 1000 элементов в порядке возрастания, сортировка по возрастанию, затем в обратном порядке, 10000 попыток: 0,0247 мс

Кажется, что .reverse() не очень затратная операция, особенно по сравнению с сортировкой.

Обратный путь будет тривиально принимать O (n), поэтому было бы лучше отсортировать его в том порядке, в котором вы хотите, чтобы они отображались (в вашем случае по убыванию)

EDToaster 22.03.2019 21:32

@JClassic Можете ли вы уточнить, почему это O (n)? Возможно ли, что JS использует двусвязный список за кулисами для списков?

Coffee_Mug 22.03.2019 21:37

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

dandavis 22.03.2019 21:43

Даже если это так, для этого все равно потребуется O(n) (проходя через каждый узел и меняя местами указатели next и prev). Вы практически не можете избежать O (n) для обратного, если только вы не используете странную структуру данных.

EDToaster 22.03.2019 21:44

Я думаю, что вы оптимизируете преждевременно.

zero298 22.03.2019 21:44

Единственный окончательный ответ: создайте тестовый пример с вашими данными на вашем устройстве, запустите его несколько тысяч раз и измерьте время, которое это занимает.

Jonas Wilms 22.03.2019 21:45

Две операции больше, чем одна. Просто отсортируйте по убыванию.

lux 22.03.2019 21:45

@coffee_mug .reverse() используется не так часто. Не имеет смысла использовать двусвязные списки для всех массивов в JS, если только некоторые из них перевернуты (кстати, интересная мысль)

Jonas Wilms 22.03.2019 21:46

@lux, если вы игнорируете все эти абстракции, происходящие под капотом, все (слишком) просто.

Jonas Wilms 22.03.2019 21:47

@JonasWilms, вы подразумеваете, что сортировка неупорядоченного списка (либо по возрастанию, либо по убыванию), а затем его обращение более эффективно, чем просто выполнение одной операции противоположной сортировки?

lux 22.03.2019 21:50

@lux Да, я думаю, что это может произойти во многих случаях. Возьмем, к примеру, [1, 3, 4, 5, 2].

Jonas Wilms 22.03.2019 21:53

@lux Я согласен, что этот вопрос может быть придирчивым, но бритва Оккама не универсальна, особенно в информатике. :)

Coffee_Mug 22.03.2019 21:56

@JonasWilms Таким образом, вы должны сначала 1) выполнить итерацию по элементам массива 2) выполнить логику, чтобы определить, будет ли asc / desc наиболее оптимальным 3) выполнить операцию сортировки 4) при необходимости отменить ее, а не 1) отсортировать способ, которым вам нужны предметы. В списке из 100 пунктов? Если бы когда-либо был случай преждевременной оптимизации/перепроектирования, это был бы он.

lux 22.03.2019 21:56

Всем спасибо за наблюдения и мысли. Как кто-то сказал, единственный окончательный способ проверить это - это... проверить. Я прогоню обе сортировки с разным количеством элементов и опубликую результаты. Жаль, что у меня не было достаточно очков, чтобы проголосовать за всех.

Coffee_Mug 22.03.2019 22:00

@lux нет, я просто говорю, что мы не можем сказать наверняка. Может быть, данные уже как-то отсортированы

Jonas Wilms 22.03.2019 22:01

Поэтому я провел несколько тестов сортировки массива по убыванию, а затем по возрастанию с обратным. Результаты довольно интересные: Запуск в хроме: — 1000 элементов в случайном порядке, нормальная сортировка по убыванию, 10000 попыток: 0,36810249999671213 мс — 1000 элементов в случайном порядке, сортировка по возрастанию, затем обратная, 10000 попыток: 0,36508599999770014 мс — 1000 элементов в порядке возрастания, нормальная сортировка по убыванию , 10000 попыток: 0,02824799999525567 мс - 1000 элементов в порядке возрастания, сортировка по возрастанию, затем в обратном порядке, 10000 попыток: 0,024710499998855086 мс

Coffee_Mug 23.03.2019 17:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
16
550
2

Ответы 2

Спецификация Ecma расплывчата в отношении Array#sort, поэтому ответ зависит от фактической реализации, предполагая, что мы говорим о V8 (Chrome, NodeJS), тогда мы можем сказать, что для списков с элементами >10 временная сложность равна O(n log(n)), а временная сложность Array#reverse это O(n).

Учитывая это, можно с уверенностью сказать, что сортировать по убыванию лучше сразу, так как sort + reverse явно дороже, чем просто sort.

сортировка по убыванию эквивалентна сортировке по возрастанию.


ОБНОВИТЬ: Как сказал Джонас в комментарии ниже, если вы заметили шаблон в своем списке (например, список уже отсортирован по возрастанию), то, вероятно, вы могли бы просто отменить его и сохранить операцию O(n log(n)). Попытка понять форму ваших данных всегда является первым шагом к оптимизации производительности.

Хм. Что делать, если массив уже отсортирован по возрастанию? Тогда сортировка + реверс может быть быстрее...

Jonas Wilms 22.03.2019 21:43

также обратите внимание, что пользовательская сортировка, использующая обратный вызов на уровне пользователя, выполняется намного медленнее, чем операция на чистом C, например reverse().

dandavis 22.03.2019 21:44

@JonasWilms отличная мысль. dandavis, я бы не стал заострять на этом внимание, потому что это трудно измерить, так как это действительно зависит от интерпретатора. Обычно вы сосредотачиваетесь на количестве операций, когда говорите о временной сложности.

Hitmands 22.03.2019 21:48

.обратный() работает за O(n), что видно из связанной спецификации. Он будет выполнять попарную замену элементов.

Чтобы ответить на ваш вопрос: sort + reverse неизбежно дороже, чем sort в одиночку, нет никакого сокращения (как может быть с двусвязным списком или какой-либо другой структурой данных).

Другие вопросы по теме