Je pensais que des liens LinkedLists étaient censés être plus rapides qu'une arracheliste lors de l'ajout d'éléments? Je viens de faire un test de combien de temps il faut pour ajouter, trier et rechercher des éléments (arraylist vs linkedlist vs hashset). J'utilisais simplement les classes Java.util pour la flaylist et LinkedList ... à l'aide des deux méthodes Ajouter (objet) à la disposition de chaque classe.
ArrayList Out Out Out LinkedList dans le remplissage de la liste ... et dans une recherche linéaire de La liste. P>
est-ce correct? Ai-je fait quelque chose de mal dans la mise en œuvre peut-être? p>
fort> em> ** * em> ** em> * * > ** * em> ** * em> *** modifier em> * em> ** ** * em> ** * em> ** * em> ** * em> * str> p> Je veux juste m'assurer que j'utilise ces choses correctement. Voici ce que je fais: p> public class ArrayListTest {
private List<String> Names;
public ArrayListTest(){
Names = new ArrayList<String>();
}
6 Réponses :
Oui, c'est vrai. Le temps de recherche linéaire est probablement plus lent dans Lorsque vous envisagez d'insérer uniquement à la fin d'une liste code> code>, LinkedList CODE> devra faire une allocation de mémoire sur chaque insertion, tandis que
ArrayList code> est autorisé à faire moins d'entre eux, ce qui lui donne
LinkedList Code> En raison de la localité de référence: The
ArrayList CODE> Les éléments sont plus proches ensemble, il y a donc moins d'href = "https: //secure.wikimedia.org/wikipedia/fr/wiki/cpu_cache "rel =" noreferrer "> cache manque . p>
ArrayList code> est la mise en œuvre de choix. P>
Ok, je suppose que cela a du sens. J'ai fait du googling ... Certains sites ont déclaré que l'ajout à la fin ou au début d'une liaison linked devrait être plus rapide que de faire la même chose avec une arraylist. Pourquoi? Je lis également un site qui a déclaré que la complexité de temps de la méthode add () de lingedList et d'arraylist est O (1). quoi? vraiment?!?!
@user: l'annexe (insérer à l'extrémité) Time pour ArrayList code> est amortizetis i> o (1), ce qui signifie que c'est O (1) en moyenne lors d'une longue série d'appouens . L'un d'entre eux peut être O (n), mais celui-ci double la capacité de sorte que la prochaine n i> d'entre eux puisse utiliser un espace préalablement alloué.
@Larsmans, cache-manquées sont le point de vente majeur des structures sauvegardées de tableau. Les structures liées sont potentiellement une erreur de cache sur chaque nœud rendant l'itération O (n) en réalité de manière significative.
@Bestssss: Je voulais dire que linkedlist code> encourt de nombreuses victimes de cache. Édité ma réponse pour la clarté.
Même lorsque la liste liée n'inclut aucun cache manque du tout, la traversée sera plus lente. En effet, la visite de chaque élément entraîne le coût de deux opérations de déséroférence au lieu de celui qui a besoin de la liste des matrices.
Hmmmm, comme il s'avère, les tableaux sont créés avec une série de références d'objets et les objets eux-mêmes résident dans des parties non liées de la mémoire. Si vous avez un éventail d'objets plutôt que de primitives, il est aussi vulnérable au cache Miss comme liste liée.
@Larsmans, mon commentaire n'était pas critique en aucun cas, j'ai été agréablement surpris de parler de quelqu'un (à part de moi) de mentionner le cache manquant lorsque vous travaillez avec une structure Java. C'était surtout des éloges.
@Zoe, les lignes de cache sont relativement courtes - 64 octets sur x86. Donc, W / 8 octets Taille de référence, c'est 7 obstacles à la cache après une erreur de cache pour arraylist. W / LinkedList Vous pouvez assumer la miss cache sur chaque élément (pas nécessaire bien sûr, mais c'est une hypothèse). Les misses de cache sont trop lentes par rapport à toute autre opération (pourraient être comme 100times plus lentes).
ArrayList est plus rapide pour accéder aux données d'index aléatoire, mais plus lente lors de l'insertion des éléments au milieu de la liste, car vous devez simplement modifier les valeurs de référence. Mais dans une liste de matrices, vous devez copier tous les éléments après l'indice inséré, un indice derrière. P>
Edit: Ne existe pas une implémentation liée à la liste qui garde le dernier élément à l'esprit? Ce faisant, cette façon accélérerait l'insertion à la fin à l'aide de la liste liée. P>
En fait, vous ne pouvez pas non plus insérer au hasard dans une liste liée non plus, afin de trouver le point d'insertion, une traversée est nécessaire.
Garder une référence au dernier élément apporte l'apaisance de O (N) à O (1), mais ne battra toujours pas un tableau dynamique lorsque vous faites beaucoup d'appouens.
Lors de l'ajout d'un élément à l'arrière d'une liste liée (en Java Linkedlist, c'est en fait une liste doublement liée), il s'agit d'une opération Donc, si vous ajoutez à l'avant de la liste, une liste linked serait considérablement plus rapide. P> O (1) code>, comme l'ajout d'un élément à l'avant de celui-ci. Ajout d'un élément sur la position code> i code> Th est d'environ un
O (i) code> opération. P>
N'EST PAS JAVA LinkedLists doublement liés en réalité - je ne pense pas que cela devrait mettre fin à vous.
Ah, je ne connais pas les détails de la mise en œuvre, mais cela pourrait être vrai. Je vais regarder et supprimer ma réponse si nécessaire.
Il semble que LinkedList est en effet une liste doublement liée, intéressante.
@Argote - Donc, cela fait-il ajouter à la fin d'une liste liée plus lentement ou plus rapide que d'ajouter à une arrayliste?
Eh bien, l'ajout au début doit être plus rapide sur une liste liée, l'ajout à la fin doit être légèrement plus rapide avec la liste des matrices.
@Argote - Nope. J'ai essayé les deux maintenant. Quoi qu'il en soit, LinkedList était plus lente que l'arraylist. Pouvez-vous regarder mon extrait de code ci-dessus et assurez-vous que je n'ai pas fait quelque chose de mal?
Eh bien, comme d'autres l'ont mentionné, cela dépendrait également de la quantité de données dans chaque liste. Une liste linked a une surcharge plus élevée qui est probablement compensée une fois que la quantité d'éléments à relocaliser sur une arracheliste dépasse certains seuils.
Pourquoi avez-vous pensé Bien sûr, périodiquement, la matrice de support de l'arrayage doit être redimensionnée (ce qui ne sera pas le cas s'il était choisi avec une capacité initiale suffisante), mais étant donné que la matrice augmente de manière exponentielle, le coût amorti sera faible et est délimité par Mettez simplement - les insertions dans les listes de matrices sont beaucoup plus simples et donc beaucoup plus rapides. P> linkedlist code> serait plus rapide? Dans le cas général, un insert dans une liste de matrices est simplement un cas de mise à jour du pointeur pour une seule cellule de réseau (avec un accès aléatoire O (1)). L'insertion LinkedListList est également un accès aléatoire, mais doit allouer un objet "cellule" pour contenir l'entrée et mettre à jour une paire de pointeurs, ainsi que em> définir finalement la référence à l'objet inséré. p>
O (lg n) code> complexité. p>
Eh bien, si nous définissons "INSERT" comme l'ajout d'un élément à une position arbitraire dans la collection (qui est imho la définition par défaut) que prévu à tous les éléments après la position. Je vous appelle d'abord sur une référence défectueuse ..
La liste liée peut être plus lente que la liste des matrices dans ces cas pour quelques raisons. Si vous insérez à la fin de la liste, il est probable que la liste des matrices dispose de cet espace déjà attribué. La matrice sous-jacente est généralement accrue dans de grandes morceaux, car il s'agit d'un processus très fastidieux. Donc, dans la plupart des cas, d'ajouter un élément dans le dos ne nécessite que de coller dans une référence, alors que la liste liée a besoin de la création d'un nœud. L'ajout à l'avant et le milieu devrait donner des performances différentes pour les deux types de liste. P>
Traversée linéaire de la liste sera toujours plus rapide dans une liste basée sur une matrice, car elle ne doit que traverser la matrice normalement. Cela nécessite une opération de déséroférence par cellule. Dans la liste liée, les nœuds de la liste doivent également être déréférencés, en prenant le double de la durée. P>
N'oubliez pas que: p>
Ainsi, par exemple, une liste liée a plus à faire pour ajouter à la fin, car il a un objet supplémentaire à allouer et à initialiser par article ajouté, mais quoi que ce coût "intrinsèque" par article, les deux structures auront des structures (1) Performances pour l'ajout à la fin de la liste, c'est-à-dire une heure "constante" par addition, quelle que soit la taille de la liste, mais cette constante sera différente entre les arraylistes vs linkedlist et probablement plus grand pour ce dernier. < / p>
D'autre part, une liste liée a une durée constante pour ajouter au début de la liste, alors que dans le cas d'une arracheliste, les éléments doivent être "shufft" ", une opération qui prend du temps proportionnelle au nombre d'éléments. Mais pour une taille de liste donnée, disons, 100 éléments, il peut toujours être plus rapide de "shufty" 100 éléments qu'il ne s'agit d'allouer et d'initialiser un seul objet de placement de la liste liée (mais au moment où vous arrivez, dites-le, mille ou un million d'objets ou quel que soit le seuil, ce ne sera pas). P>
Donc, dans vos tests, vous souhaitez probablement examiner à la fois le temps "brut" des opérations à une taille donnée et comment ces opérations échelle em> comme la taille de la liste se développe. P>
Cela dépend ... Qu'est-ce que votre code de test ressemble? Si vous initialisez l'arraylist à une taille connue, alors la flaylist serait probablement plus rapide. LinkedList est livré avec des frais généraux supplémentaires dans ce que chaque élément doit être enveloppé dans un nœud afin qu'il puisse contenir des références à la prev et à la suivante. Les problèmes de performance de l'arraylist proviennent d'initialiser un ensemble de support totalement nouveau lorsque la capacité existante a été atteinte et copie tous les éléments sur le nouveau tableau.
@Mark - Nope, pas d'initialisation de l'arraylist à une taille connue.