web-dev-qa-db-fra.com

Lequel est le plus rapide, ArrayList ou LinkedList?

List li = new LinkedList();

for (int i = 0; i < 100; i++) {
    li.add(i);
}

long start1 = System.nanoTime();
li.get(57);

long end1 = System.nanoTime();
long diff1 = end1-start1;

System.out.println("Time taken by LinkedList = "+diff1);

List al = new ArrayList();
for (int i = 0; i < 100; i++) {
    al.add(i);
}

Quelles que soient les opérations que j'effectue sur les deux listes, lorsque j'imprime le temps mis, ArrayList est toujours plus rapide que LinkedList. Quelqu'un peut-il expliquer lequel fonctionne le mieux en termes de temps? Indiquez-moi également si quelque chose ne va pas dans le code. Merci!

14
Anjan Baradwaj

Si vous devez effectuer beaucoup d'insertions et une recherche moins fréquente, utilisez un LinkedList. Utilisez ArrayList si vous effectuez plus de recherches que d'insertions.

La raison est la suivante: ArrayList est soutenu par un tableau ayant une capacité initiale. Par conséquent, si vous continuez à insérer des éléments dans la liste, il devra réajuster sa capacité de groupe pour prendre en charge les éléments récemment insérés. Il peut également être nécessaire de déplacer les éléments existants si vous effectuez des insertions spécifiques à un index. D'autre part, LinkedList est soutenu par une liste chaînée, la création d'un élément s'exécutant toujours dans un temps constant - créez un élément et affectez-le à la fin de la liste. Aucun réajustement ne se produit ici.

Maintenant, pour extraire un élément de la ArrayList, il faudra toujours un temps constant, car il peut facilement indexer le tableau de sauvegarde en un temps constant. Mais récupérer un élément de la LinkedList peut vous amener à parcourir toute la liste liée pour trouver le nœud de l’élément. Par conséquent, sa performance est inférieure à ArrayList dans ce cas.

Dans la discussion ci-dessus, vous pouvez voir que lorsque vous avez plus d’insert à faire, LinkedList surperformera toujours ArrayList car ce dernier a un coût de redimensionnement interne associé aux inserts alors que le précédent ne le fait pas. D'autre part, si vous avez des insertions peu fréquentes et des recherches fréquentes, ArrayList surperformera toujours LinkedList car pour cette dernière option, vous devrez peut-être parcourir l'intégralité de la structure de liste liée pour trouver l'élément souhaité, tandis que le premier pourra rapidement trouver vos éléments. avec tableau d'indexation à temps constant.

Tous les effets ci-dessus sont visibles et affectent les performances de votre application lorsque vous traitez un grand nombre d'éléments (par exemple, des milliers d'éléments). Pour un nombre réduit d'éléments, la différence de performances n'est pas tout à fait visible.

En ce qui concerne votre code, vous avez de sérieux problèmes. Pour commencer, vous utilisez un type brut, ce qui est mauvais car vous perdez tout le type de sécurité que les génériques ont à offrir. Vous devez toujours utiliser la version générique de l'API Collection lorsque vous écrivez un nouveau code. Alors, changez votre code comme suit - 

List<Integer> li = new LinkedList<Integer>();
for (int i = 0; i < 100; i++) {
    li.add(i);
}

long start1 = System.nanoTime();
li.get(57);

long end1 = System.nanoTime();
long diff1 = end1 - start1;

System.out.println("Time taken by LinkedList = "+diff1);

List<Integer> al = new ArrayList<Integer>();
for (int i = 0; i < 100; i++) {
    al.add(i);
}

Voir Effective Java, Rubrique 23: N'utilisez pas de types bruts dans le nouveau code pour une explication détaillée.

MODIFIER

D'après la discussion dans les commentaires, il devrait être évident pour vous que si vous devez insérer des éléments au milieu de la liste ou à un emplacement aléatoire, alors ArrayList surpasse LinkedList en termes de performances, car le premier utilisera memcpy pour décaler le des éléments extrêmement rapides, et ceux-ci devront parcourir l'index souhaité pour insérer correctement le nouvel élément, ce qui est plus lent. Donc, pour les insertions aléatoires ArrayList surpasse également LinkedList. Le seul cas où LinkedList surpasse ArrayList est que si vous insérez uniquement à la fin de votre liste, et qu'il existe beaucoup de ces insertions.

14
MD Sayem Ahmed

La liste de tableaux sera toujours plus rapide que la liste liée en termes de lecture. ArrayList est fondamentalement une implémentation de tableau et la mémoire allouée pour un tableau est séquentielle afin que la lecture soit plus rapide. Mais lorsque vous utilisez une liste qui nécessite une insertion ou une suppression entre les listes, la liste chaînée est plus rapide. Parce qu'il suffisait d'ajouter les liens entre les nœuds. Dans ces deux cas, la liste de tableaux sera plus lente.Usage peut être:

ArrayList - Une opération plus rapide de lecture, insertion, suppression entre la liste est plus lente . Liste liée - Une opération de lecture lente par rapport à Array List mais l'insertion, la suppression entre la liste est plus rapide.

2
Vijay

ArrayList est sauvegardé par array et LinkedList sauvegardé Les nœuds liés à refernece.

Donc, l'opération sur ArrayList est en réalité une opération d'évaluation sur array. L'opération add s'exécute en temps constant amorti, c'est-à-dire que l'ajout de n éléments nécessite O(n) time. Toutes les autres opérations se déroulent en temps linéaire (en gros). Le facteur constant est faible par rapport à celui de l'implémentation LinkedList.

et sur LinkedList, toutes les opérations se déroulent comme prévu pour une liste doublement chaînée. Les opérations qui indexent dans la liste parcourent la liste depuis le début ou la fin, selon ce qui est le plus proche de l'index spécifié.

en savoir plus sur la documentation -

1

LinkedList impliquera la création d'un nouveau nœud lors de l'ajout de chaque élément, alors qu'il ne figure pas dans la liste de tableaux. 

Si vous connaissez la taille initiale, transmettez-le à ArrayList lors de la création, cela évite la reconstruction du tableau Comme new ArrayList(100);

0
upog