ArrayDeque vs ArrayList для реализации стека

В документации для ArrayDeque указано:

Этот класс, вероятно, будет быстрее, чем Stack при использовании в качестве стека, и быстрее, чем LinkedList при использовании в качестве очереди.

Не упоминается различие между использованием ArrayDeque в качестве стека и использованием ArrayList. Вы можете использовать ArrayList как стек следующим образом.

list.add(object);                      // push
object = list.remove(list.size() - 1); // pop

Я обнаружил, что, когда я использовал только ArrayList, его производительность хуже, чем ArrayDeque. Что объясняет это различие? Разумеется, это не просто призывы к size()? Внутри, как ArrayList, так и ArrayDeque реализованы с использованием Object[], который при необходимости заменяется большим массивом, поэтому, конечно, производительность должна быть примерно одинаковой?

Ответы

Ответ 1

Основное различие между обеими реализациями - стратегия изменения размера

  • ArrayList изменяется до нового размера oldCapacity + (oldCapacity >> 1), что приводит к увеличению до 50%. Емкость по умолчанию - 10, что приводит к емкости после изменения размера 15,22,33,49,73,109,163,244,366...

  • ArrayDeque всегда изменяется до степени 2. При изменении размера емкость удваивается. Начиная с значения по умолчанию 16, емкость повторения после изменения размера составляет 32,64,128,256,...

Таким образом, ArrayDeque достигает более высоких мощностей с гораздо меньшей степенью изменения размера, что дорого из-за копирования массива. То есть для хранения 256 в ArrayList по умолчанию, для этого требуется 9 вызовов с изменением размера, в то время как для ArrayDeque требуется только 4. Копирование массива может быть быстрым, но также может потребовать, чтобы GC освободил место для новых наборов данных в дополнение к расходам на копирование памяти (где ArrayDeque также может работать лучше благодаря выравниванию по мощности 2).

Обе структуры данных имеют наилучшую степень сложности O (1) для push и pop через прямой доступ на head и tail (ArrayDequeue), соответственно добавляя и удаляя (Last) size (ArrayList)