La documentation de ArrayDeque
dit:
Cette classe est susceptible d'être plus rapide que Stack lorsqu'elle est utilisée en tant que pile et plus rapide que LinkedList lorsqu'elle est utilisée en tant que file d'attente.
Il n'y a aucune mention de la différence entre l'utilisation d'un ArrayDeque
comme pile et l'utilisation d'un ArrayList
. Vous pouvez utiliser un ArrayList
comme pile comme suit.
list.add(object); // Push
object = list.remove(list.size() - 1); // pop
J'ai constaté que lorsque j'utilisais un ArrayList
de cette manière uniquement, ses performances étaient pires que ArrayDeque
. Qu'est-ce qui explique cette différence? Sûrement, ce ne peut pas être juste les appels à size()
? En interne, ArrayList
et ArrayDeque
sont implémentées à l'aide d'un Object[]
Qui est remplacé par un tableau plus grand si nécessaire, donc les performances devraient être à peu près les mêmes?
La principale différence entre les deux implémentations est la stratégie de redimensionnement
ArrayList
est redimensionné à une nouvelle taille de oldCapacity + (oldCapacity >> 1)
, résultant en une augmentation de ~ 50%. La capacité par défaut est 10, ce qui donne une capacité après redimensionnement de 15,22,33,49,73,109,163,244,366 ...
ArrayDeque
est toujours redimensionné à une puissance de 2. Au redimensionnement, la capacité est doublée. À partir de la valeur par défaut de 16, les capacités de résolution après redimensionnement sont 32,64,128,256, ...
Ainsi, l'ArrayDeque atteint des capacités plus élevées avec une opération de redimensionnement beaucoup moins importante, ce qui est coûteux en raison de la copie de la matrice. C'est à dire. pour stocker 256 dans ArrayList de taille par défaut, il nécessite 9 appels de redimensionnement, tandis que ArrayDeque n'en a besoin que de 4. La copie de la matrice peut être rapide, mais peut également nécessiter un GC pour libérer de l'espace pour les nouveaux ensembles de données, en plus de la copie de la mémoire les coûts (où l'ArrayDeque pourrait également mieux fonctionner en raison de son alignement sur la puissance de 2).
Les deux infrastructures de données ont une complexité optimale de O(1) pour Push and pop via un accès direct sur head
& tail
(ArrayDequeue) respectivement ajouter et supprimer (Dernier) size
(ArrayList)