Since
- they are both contiguous memory containers;
- 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
?
Since
Why whould anyone prefer std::vector
to std::deque
?
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 prefervector
. In addition, since there is some extra bookkeeping, other ops are probably (slightly) more expensive than their equivalentvector
operations. On the other hand, using many/large instances ofvector
may lead to unnecessary heap fragmentation (slowing down calls tonew
).Also, as pointed out elsewhere on StackOverflow, there is more good discussion here: http://www.gotw.ca/gotw/054.htm .
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:The second of these is lesser known, but for very large collection sizes:
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 avector
will probably get rejected at some point with abad_alloc
, the optimistic nature of the allocator is likely to always grant the request for the smaller buffer requested by adeque
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...)
According to http://www.cplusplus.com/reference/stl/deque/, "unlike vectors, deques are not guaranteed to have all its elements in contiguous storage locations, eliminating thus the possibility of safe access through pointer arithmetics."
Deques are a bit more complicated, in part because they don't necessarily have a contiguous memory layout. If you need that feature, you should not use a deque.
(Previously, my answer brought up a lack of standardization (from the same source as above, "deques may be implemented by specific libraries in different ways"), but that actually applies to just about any standard library data type.)
You woudn't prefer vector to deque acording to these test results (with source).
Of course, you should test in your app/environment, but in summary:
Some more musings, and a note to consider circular_buffer.
On the one hand, vector is quite frequently just plain faster than deque. If you don't actually need all of the features of deque, use a vector.
On the other hand, sometimes you do need features which vector does not give you, in which case you must use a deque. For example, I challenge anyone to attempt to rewrite this code, without using a deque, and without enormously altering the algorithm.
A deque is a sequence container which allows random access to it's elements but it is not guaranteed to have contiguous storage.