Почему ArrayDeque лучше, чем LinkedList
Я пытаюсь понять , почему Java ArrayDeque лучше, чем Java LinkedList, поскольку оба они реализуют интерфейс Deque.
Я почти не вижу, чтобы кто-то использовал ArrayDeque в своем коде. Если кто-то проливает больше света на то, как ArrayDeque реализован, было бы полезно.
Если я это понимаю, я буду более уверенно использовать его. Я не мог четко понять реализацию JDK в том, как он управляет заголовками и хвостами.
Ответы
Ответ 1
Связанные структуры, возможно, являются наихудшей структурой для итерации с пропуском кеша для каждого элемента. Кроме того, они потребляют больше памяти.
Если вам нужно добавить/удалить оба конца, ArrayDeque значительно лучше, чем связанный список. Случайный доступ к каждому элементу также O (1) для циклической очереди.
Единственная лучшая операция связанного списка - удаление текущего элемента во время итерации.
Ответ 2
ArrayDeque
является новым с Java 6, поэтому многие коды (особенно проекты, которые пытаются быть совместимыми с более ранними версиями Java) не используют его.
В некоторых случаях это "лучше", потому что вы не выделяете node для каждого вставляемого элемента; вместо этого все элементы хранятся в гигантском массиве, который изменяется, если он заполняется.
Ответ 3
Я считаю, что основным недостатком производительности в LinkedList
является тот факт, что всякий раз, когда вы нажимаете на любой конец deque, за сценой реализация выделяет новый связанный список node, который по существу включает JVM/OS и это дорого. Кроме того, всякий раз, когда вы выходите из любого конца, внутренние узлы LinkedList
становятся доступными для сбора мусора и что больше работы за сценой.
Если это может быть интересно, у меня есть доказательство того, что добавление элемента в ArrayList
или ArrayDeque
выполняется в аморифицированном постоянном времени; обратитесь к этому.
Ответ 4
Доступ к элементу в ArrayDeque всегда быстрее по сравнению с LinkedList с O (1) для доступа к элементам. В связанном списке для поиска последнего элемента потребуется O (N).
ArrayDeque эффективен с точки зрения памяти, поскольку вам не нужно отслеживать следующий node, в отличие от Linked List.
Даже в соответствии с документацией по Java, было указано, что
ArrayDeque - это реализация интерфейса Deque Resizable-array. Недопустимые ограничения на пропускную способность массива; они растут по мере необходимости для поддержки использования. Они не являются потокобезопасными; в отсутствие внешней синхронизации они не поддерживают одновременный доступ несколькими потоками. Нулевые элементы запрещены. Этот класс, вероятно, будет быстрее, чем Stack при использовании в качестве стека, и быстрее, чем LinkedList при использовании в качестве очереди.
Бенчмаркинг этих двух доказательств того, что ArrayDeque быстрее.
Ответ 5
Все люди, критикующие LinkedList
, думают о каждом другом, который использовал List
в Java, вероятно, используют ArrayList
и LinkedList
большую часть времени, потому что они были до Java 6 и потому, что те которые учат как начало в большинстве книг.
Но это не значит, я бы слепо взял сторону LinkedList
или ArrayDeque
. Если вы хотите узнать, посмотрите нижеуказанный ориентир выполненный Брайаном.
В тестовой настройке учитывается:
- Каждый тестовый объект представляет собой строку с 500 символами. Каждая строка является другим объектом в памяти.
- Размер тестового массива будет изменяться во время тестов.
- Для каждой комбинации размеров массива/очереди-реализации выполняется 100 тестов и вычисляется среднее время на тест.
- Каждый тест состоит из заполнения каждой очереди всеми объектами, а затем их удаления.
- Измерьте время в миллисекундах.
Результат теста:
- Ниже 10000 элементов тесты LinkedList и ArrayDeque усредняются на уровне менее 1 мс.
- По мере увеличения наборов данных различия между средним временем тестирования ArrayDeque и LinkedList становятся больше.
- При размере теста, равном 9 900 000 элементов, подход LinkedList занял ~ 165% дольше, чем подход ArrayDeque.
Graph:
![введите описание изображения здесь]()
Вынос:
- Если ваше требование хранит 100 или 200 элементов, это не сделает
большую часть разницы, используя любую из очередей.
- Однако, если вы работаете на мобильных устройствах, вы можете использовать
ArrayList
или ArrayDeque
с хорошей догадкой о максимальной емкости
что список может потребоваться из-за строгого ограничения памяти.
- Существует много кода, написанных с помощью
LinkedList
так осторожно, чтобы решить, использовать ArrayDeque
, особенно потому, что он НЕ реализует интерфейс List
(я думаю, что причина достаточно большой). Возможно, ваша кодовая база очень часто разговаривает с интерфейсом "Список", и, возможно, вы решите перейти с помощью ArrayDeque
. Использование его для внутренних реализаций может быть хорошей идеей...
Ответ 6
хотя ArrayDeque<E>
и LinkedList<E>
реализовали интерфейс Deque<E>
, но ArrayDeque использует в основном массив Object E[]
для сохранения элементов внутри своего объекта, поэтому он обычно использует индекс для определения элементов головы и хвоста.
Одним словом, он просто работает как Deque (со всем методом Deque), однако использует структуру данных массива. Что касается того, что лучше, зависит от того, как и где вы их используете.
Ответ 7
Сложность времени для ArrayDeque для доступа к элементу - это O (1), а для LinkList - O (N) для доступа к последнему элементу. ArrayDeque не является потокобезопасным, поэтому необходима синхронизация вручную, чтобы вы могли получить к нему доступ через несколько потоков, и поэтому они быстрее.