Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why prefer std::vector over std::deque? [duplicate]

Tags:

c++

stl

They both have access complexity of O(1) and random insertion/removal complexity of O(n). But vector costs more when expanding because of reallocation and copy, while deque does not have this issue.

It seems deque has a better performance, but why most people use vector instead of deque?

like image 919
SwiftMango Avatar asked Sep 26 '13 14:09

SwiftMango


3 Answers

Personally, I prefer using deque (I always end up spoiling myself and having to use push_front for some reason or other), but vector does have its uses/differences, with the main one being:

vector has contiguous memory, while a deque allocates via pages/chunks. Note, the pages/chunks are fairly useful: constant-time insert/erase on the front of the container. It is also typical that a large block of memory broken up into a series of smaller blocks is more efficient than a single block of a memory.

You could also argue that, because deque is 'missing' size reservation methods (capacity/reserve), you have less to worry about.

I highly suggest you read Sutters' GotW on the topic.

like image 188
Mohammed Hossain Avatar answered Oct 18 '22 10:10

Mohammed Hossain


why most people use vector instead of deque?

Because this is what they have been taught.

vector and deque serve slightly different purposes. They can both be used as a simply container of objects, if that's all you need. When learning to program C++, that is all most people need -- a bucket to drop stuff in to, get stuff out of, and walk over.

When StackOverflow is asked a question like "which container should I use by default," the answer is almost invariably vector. The question is generally asked from the context of learning to program in C++, and at the point where a programmer is asking such a question, they don't yet know what they don't know. And there's a lot they don't yet know. So, we (StackOverflow) need a container that fits almost every need for better or worse, can be used in almost any context, and doesn't require that the programmer has asked all the right questions before landing on something approximating the correct answer. Furthermore, the Standard specifically recommends using vector. vector isn't best for all uses, and in fact deque is better than vector for many common uses -- but it's not so much better for a learning programmer that we should vary from the Standard's advice to newbie C++ programmers, so StackOverflow lands on vector.

After having learned the basics of the syntax and, shall we say, the strategies behind programming in C++, programmers split in to two branches: those who care to learn more and write better programs, and those who don't. Those who don't will stick on vector forever. I think many programmers fall in to this camp.

The rarer programmers who try to move beyond this phase start asking other questions -- questions like you've asked here. They know there is lots they don't yet know, and they want to start discovering what those things are. They will quickly (or less quickly) discover that when choosing between vector and deque, some questions they didn't think to ask before are:

  1. Do I need the memory to be contigious?
  2. Do I need to avoid lots of reallocations?
  3. Do I need to keep valid iterators after insertions?
  4. Do I need my collection to be compatible with some ancient C-like function?

Then they really start thinking about the code they are writing, discover yet more stuff they don't know, and the beat goes on...

like image 28
John Dibling Avatar answered Oct 18 '22 11:10

John Dibling


But vector costs more when expanding because of reallocation and copy

While it's true that vector sometimes has to reallocate its array as it grows, it will grow exponentially so that the amortised complexity is still O(1). Often, you can avoid reallocations by judicious use of reserve().

It seems deque has a better performance

There are many aspects to performance; the time taken by push_back is just one. In some applications, a container might be modified rarely, or populated on start-up and then never modified. In cases like that, iteration and access speed might be more important.

vector is the simplest possible container: a contiguous array. That means that iteration and random access can be achieved by simple pointer arithmetic, and accessing an element can be as fast as dereferencing a pointer.

deque has further requirements: it must not move the elements. This means that a typical implementation requires an extra level of indirection - it is generally implemented as something like an array of pointers to arrays. This means that element access requires dereferencing two pointers, which will be slower than one.

Of course, often speed is not a critical issue, and you choose containers according to their behavioural properties rather than their performance. You might choose vector if you need the elements to be contiguous, perhaps to work with an API based on pointers and arrays. You might choose deque or list if you want a guarantee that the elements won't move, so you can store pointers to them.

like image 35
Mike Seymour Avatar answered Oct 18 '22 12:10

Mike Seymour