Производительность Java - Collections.sort()
Im использует Collections.sort() для сортировки LinkedList, элементы которого реализуют интерфейс Comparable, поэтому они сортируются в натуральном порядке. В документации javadoc говорится, что этот метод использует алгоритм mergesort, который имеет производительность n * log (n).
Мой вопрос в том, есть ли более эффективный алгоритм для сортировки моего LinkedList?
Размер этого списка может быть очень высоким, а сортировка также будет очень частым.
Спасибо!
Ответы
Ответ 1
O(N log N)
очень хорош асимптотически. Тем не менее, существует линейное время O(N)
сортировка без сравнения, например. подсчет сортировки и сортировка ковша. Это полезно, когда, например, вы сортируете миллионы и миллионы целых чисел, но они между 1..10.
Кроме того, если список "почти отсортирован", то, по-видимому, в некоторых сценариях будет показано, что в противном случае квадратичная сортировка вставки будет лучше.
Независимо от того, применимо ли это или даже стоит реализовать, зависит от ваших результатов профилирования. Я бы сказал, что, если он не покажет, что этот вид будет узким местом, не беспокойтесь об этом.
См. также
Связанные вопросы
Ответ 2
Если вы скажете, что список будет отсортирован "очень часто", вам следует рассмотреть возможность хранения списка в отсортированном заявлении все время, например, используя дерево вместо LinkedList
. Возможно, вы даже можете использовать SortedSet
вместо List
, если у вас нет дублированных значений и вам не нужны какие-либо операции с списком (поскольку вы все равно их сортируете). Проверьте TreeSet
класс реализации SortedSet
.
Эта реализация обеспечивает гарантированную log (n) временную стоимость для основных операций (добавление, удаление и содержит).
Если вы хотите итерации по этому "списку" (на самом деле это Set), вы можете использовать Iterator класса.
Возвращает итератор по элементам в этом наборе в порядке возрастания.
Если у вас есть повторяющиеся значения внутри Списка, вы должны использовать некоторые трюки (например, поместить значение в новый класс, который также получил некоторую дельта для сортировки равного объекта)
Ответ 3
Алгоритм общего сортировки лучше, чем n*log(n)
. И это довольно быстро. По общему я имею в виду, что ваши данные не имеют специальных свойств.
Ответ 4
Я экспериментирую с большими наборами данных (ГБ данных) и реализовал сортировку слияния (есть хороший пример @googlecode). Тем не менее, я использую Collection.sort() для предварительной сортировки временных буферов, и по моему опыту Collection.sort() становится смехотворно медленным с определенным порогом данных. С вспомогательным буфером 96 МБ я могу сортировать один из этих буферов примерно за 30 секунд (обратите внимание: это сильно зависит от используемых вами компараторов - я использую настраиваемый макет столбца с довольно сложным синтаксическим анализатором столбцов), но увеличивая его до размера блока размером 128 МБ время перескакивает более 3 минут. Это никак не связано с линейным (или почти линейным) поведением, которое я могу наблюдать за меньшими кусками. Это так сильно влияет на то, что слияние сортируется с меньшими буферами почти (?) Во всех случаях быстрее, чем в сортировке памяти с использованием буфера 128 МБ. Чтобы сделать это кратким: сортировка слияния - это способ поиска больших наборов данных за пределами границы 100 МБ. Я не могу ответить на вопрос, почему это так, и эти числа могут быть даже зависимыми от машины (мой OS-X на 2,6 ГГц памяти i7 и 16 ГБ).
Ответ 5
В терминах сортировки списка нет, все сопоставления, основанные на общих данных, это O (N log (N)).
Если ваше обращение связано с вставками, вы можете попытаться выполнить пакетные вставки, а затем объединить сортировку с основным списком - если у вас есть новые элементы B, вы сортируете их в O (B-журнал (B)), затем выполните одноуровневое слияние двух списков, которое равно O (N + B).
Если ваше обращение связано с изменением значений элементов, вы можете выполнить аналогичную доработку, если вы измените изменяемые значения на неизменяемые и рассматриваете изменения как пакет вставки и удаления. В противном случае вы не сможете избежать сортировки всего списка.
Если ваши требования позволяют это, тогда существуют различные структуры не связанных списков, такие как TreeSet, которые поддерживают упорядоченный порядок более эффективно, но будут терпеть неудачу, если значения изменяемы.