Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would I prefer using vector to deque

Since

  1. they are both contiguous memory containers;
  2. feature wise, deque has almost everything vector has but more, since it is more efficient to insert in the front.

Why whould anyone prefer std::vector to std::deque?

like image 324
Leon Avatar asked Mar 17 '11 20:03

Leon


People also ask

When would you use a deque in preference to a vector?

One should choose deque over vector if he wants to either add or delete from both the ends like implementing a Queue. When to choose vector over deque: One should choose vector if insertion or deletions are required mostly in end like implementing a Stack.

Is deque more efficient than vector?

Deque stands for Double-ended queues that are a sequence of containers specifically used for feature expansion and contraction on both ends, almost similar to Vectors. There is a slight difference between Deque and Vector, which is like Deque is a little more efficient than Vector in terms of insertion and deletion.

Which is faster deque or vector?

The deque is a bit slower than the vector, that is logical because here there are more cache misses due to the segmented parts. The performance of the list are still poor but the gap is decreasing. The interesting point is that deque is now faster than vector.

Can I use vector as queue?

You "can" use a vector over a queue, if the queue lifetime is short or if you know the maximum size of your queue. Just use a vector, push_back in it, and keep an index of where your "head" is.


2 Answers

Elements in a deque are not contiguous in memory; vector elements are guaranteed to be. So if you need to interact with a plain C library that needs contiguous arrays, or if you care (a lot) about spatial locality, then you might prefer vector. In addition, since there is some extra bookkeeping, other ops are probably (slightly) more expensive than their equivalent vector operations. On the other hand, using many/large instances of vector may lead to unnecessary heap fragmentation (slowing down calls to new).

Also, as pointed out elsewhere on StackOverflow, there is more good discussion here: http://www.gotw.ca/gotw/054.htm .

like image 147
phooji Avatar answered Oct 04 '22 03:10

phooji


To know the difference one should know how deque is generally implemented. Memory is allocated in blocks of equal sizes, and they are chained together (as an array or possibly a vector).

So to find the nth element, you find the appropriate block then access the element within it. This is constant time, because it is always exactly 2 lookups, but that is still more than the vector.

vector also works well with APIs that want a contiguous buffer because they are either C APIs or are more versatile in being able to take a pointer and a length. (Thus you can have a vector underneath or a regular array and call the API from your memory block).

Where deque has its biggest advantages are:

  1. When growing or shrinking the collection from either end
  2. When you are dealing with very large collection sizes.
  3. When dealing with bools and you really want bools rather than a bitset.

The second of these is lesser known, but for very large collection sizes:

  1. The cost of reallocation is large
  2. The overhead of having to find a contiguous memory block is restrictive, so you can run out of memory faster.

When I was dealing with large collections in the past and moved from a contiguous model to a block model, we were able to store about 5 times as large a collection before we ran out of memory in a 32-bit system. This is partly because, when re-allocating, it actually needed to store the old block as well as the new one before it copied the elements over.

Having said all this, you can get into trouble with std::deque on systems that use "optimistic" memory allocation. Whilst its attempts to request a large buffer size for a reallocation of a vector will probably get rejected at some point with a bad_alloc, the optimistic nature of the allocator is likely to always grant the request for the smaller buffer requested by a deque and that is likely to cause the operating system to kill a process to try to acquire some memory. Whichever one it picks might not be too pleasant.

The workarounds in such a case are either setting system-level flags to override optimistic allocation (not always feasible) or managing the memory somewhat more manually, e.g. using your own allocator that checks for memory usage or similar. Obviously not ideal. (Which may answer your question as to prefer vector...)

like image 30
CashCow Avatar answered Oct 04 '22 04:10

CashCow