Depuis
- ils sont à la fois continue de mémoire contenant
- caractéristique sage, deque a presque vecteur a plus mais, étant donné qu'il est plus efficace de les insérer dans le front.
pourquoi devrait tout préférez vecteur pour deque?
Depuis
pourquoi devrait tout préférez vecteur pour deque?
Éléments d'un deque
sont no contiguës dans la mémoire ; vector
sont garantis. Ainsi, si vous devez interagir avec une bibliothèque C simple qui a besoin de tableaux contigus, ou si vous vous souciez (beaucoup) de la localité spatiale, vous pouvez préférer vector
. En outre, étant donné qu'il y a une comptabilité supplémentaire, les autres opérations sont probablement (légèrement) plus chères que leur équivalent. vector
opérations. D'autre part, l'utilisation d'un grand nombre d'instances de vector
peut entraîner une fragmentation inutile du tas (ce qui ralentit les appels à new
).
En outre, comme il a été souligné ailleurs sur StackOverflow Il y a d'autres bonnes discussions ici : http://www.gotw.ca/gotw/054.htm .
Pour faire la différence, il faut savoir comment deque
est généralement mis en œuvre. La mémoire est allouée en blocs de taille égale, qui sont enchaînés les uns aux autres (sous la forme d'un tableau ou éventuellement d'un vecteur).
Pour trouver le nième élément, il faut donc trouver le bloc approprié, puis accéder à l'élément qu'il contient. C'est un temps constant, car il y a toujours exactement deux recherches, mais c'est toujours plus que le vecteur.
vector
fonctionne également bien avec les API qui veulent un tampon contigu parce qu'il s'agit d'API C ou qu'elles sont plus polyvalentes en ce sens qu'elles peuvent prendre un pointeur et une longueur. (Vous pouvez donc avoir un vecteur en dessous ou un tableau normal et appeler l'API à partir de votre bloc de mémoire).
Où deque
a ses plus grands avantages :
La seconde est moins connue, mais elle concerne des collections de très grande taille :
Lorsque j'ai eu à traiter de grandes collections dans le passé et que je suis passé d'un modèle contigu à un modèle par blocs, nous avons pu stocker une collection environ cinq fois plus grande avant de manquer de mémoire dans un système 32 bits. Cela s'explique en partie par le fait que, lors de la réallocation, il était nécessaire de stocker l'ancien bloc ainsi que le nouveau avant de copier les éléments.
Ceci étant dit, vous pouvez avoir des problèmes avec std::deque
sur les systèmes qui utilisent une allocation de mémoire "optimiste". Alors que ses tentatives de demander une grande taille de mémoire tampon pour une réaffectation d'un fichier vector
sera probablement rejetée à un moment ou à un autre avec un bad_alloc
l'allocateur étant optimiste, il est probable qu'il accède toujours à la demande de la plus petite mémoire tampon demandée par un utilisateur. deque
et cela peut amener le système d'exploitation à tuer un processus pour essayer d'acquérir de la mémoire. Quel que soit celui qu'il choisira, il risque de ne pas être très agréable.
Dans ce cas, les solutions de contournement consistent soit à définir des drapeaux au niveau du système pour ignorer l'allocation optimiste (ce qui n'est pas toujours possible), soit à gérer la mémoire plus manuellement, par exemple en utilisant votre propre allocateur qui vérifie l'utilisation de la mémoire, ou quelque chose de similaire. Ce n'est évidemment pas la solution idéale. (Ce qui peut répondre à votre question sur le vecteur à privilégier...)
J'ai mis en œuvre à la fois vector et deque à plusieurs reprises. deque est beaucoup plus compliqué du point de vue de la mise en œuvre. Cette complication se traduit par un code plus important et plus complexe. Vous constaterez donc généralement une augmentation de la taille du code lorsque vous choisirez deque plutôt que vector. Vous pouvez également constater un léger gain de vitesse si votre code n'utilise que les éléments pour lesquels le vecteur excelle (c.-à-d. push_back).
Si vous avez besoin d'une file d'attente à double extrémité, deque est le vainqueur incontesté. Mais si vous effectuez la plupart de vos insertions et effacements à l'arrière, vector sera le grand gagnant. Si vous n'êtes pas sûr de vous, déclarez votre conteneur avec un typedef (pour qu'il soit facile de passer de l'un à l'autre), et mesurez.
Question : le comité a-t-il envisagé d'ajouter un hybride des deux (par exemple, un "deck") à C++ ? vector
.) J'ai écrit une implémentation dont le lien figure ci-dessous dans ma réponse . Il peut être aussi rapide qu'un vector
mais beaucoup plus largement applicable (par exemple, lors de la création d'une file d'attente rapide).
Je ne pense pas qu'une "liste de vecteurs" soit correcte : j'ai cru comprendre que la plupart des implémentations étaient un "vecteur de pointeurs vers des tableaux", bien que cela dépende de votre définition de "liste" (j'ai lu "liste" comme "liste liée", ce qui ne répondrait pas aux exigences de complexité).
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
21 votes
Deque n'est pas un conteneur à mémoire continue.
0 votes
@ravil Non, c'est le doublon qui pointe vers cette question.
0 votes
Je voulais modifier "deque has almost vector has but more" pour que cela ait un sens, mais je ne suis pas sûr de ce que cela est censé signifier.
2 votes
Il est difficile de croire qu'une question comportant une erreur factuelle flagrante non corrigée ait obtenu 34 voix.
2 votes
@underscore_d c'est pour cela que c'est une question. Si c'était une réponse, ce serait une autre histoire ;)
0 votes
Bo Qian a donné une très bonne explication : Vecteur vs Deque - I et Vecteur vs Deque - II