A situation where deque has to be used

Source: Internet
Author: User

In the past, we thought that the vector and deque were almost the same. In terms of efficiency, deque and vector were close, so we should simply use the efficient vector.
However, if I ignore the other party, there is a reason for a transaction to exist.ProgramThe hidden bug in it gave me the reason why I had to use deque,
The structure of deque and vector is similar, but it is a multi-segment continuous space. If the space of the vector is insufficient, allocate the space again and copy all the data to the new space,
Deque won't do this. It will open up another continuous space to store data, so deque is higher than vector in terms of storage efficiency, but deque is different from linked list, it can be said that it is a compromise between the sequential storage structure and the chained storage structure. Today I wroteCode, Is such a structure

Vector <serializedentity> archiveentities, serialized storage // removes the pointer's data read/write method, so the vector <serializedentity>
So: entity * ent = & archive [0 ];
This archiveentities is okay if it is not changed, but if the sequence set dynamically adds data and there is no reserved space, the whole set will be re-allocated with continuous space, so the reference will also be "invalid", which makes me a headache. This reminds me of deque, which is really great and will not reorganize the space, when necessary, other consecutive spaces are opened up. Although the Read efficiency is reduced
This loss is negligible for my program. I/O data itself seldom traverses access, but it can "Reference" The program well without worrying about invalid references, in this regard, deque is indeed a good choice.

Find an articleArticleTo share with you, we should also prove my point of view:
OPERATOR []

OPERATOR [] is used to retrieve data by subscript. Obviously, the list complexity is O (n), which is very slow. The values of vector and deque are O (1 ). Let's imagine the implementation of deque: operator:

 

_ E deque: operator [] (int I)
{
Return m_storage [I/blocksize] [I % blocksize];
}

 

We can see that deque only has one more memory access than vector.

Spatial Performance Analysis

Push_back

Vector

Unfortunately, if the vector uses the N * 2 memory growth model (normally), the space complexity is 2 * n in the worst case, the best case is n (all memory is used ). On average, the space complexity is 1.5 * n. That is to say, almost half of the memory is wasted.

List

The waste of list space is much less than that of vector. Its spatial complexity is (1 + sizeof (pointer) * 2/sizeof (_ E) * n. if we make the list Storage Element pointer (I .e. _ e = pointer), the space complexity is 3 * n, which is a waste of space than the vector.

Deque

Deque's worst case space complexity is n + sizeof (pointer) * 2 * n/(blocksize * sizeof (_ E )) (assume that vector uses a 2 * n growth model, and the average complexity is changed to 1.5 in formula 2 ). If the saved element is Pointer (I .e. _ e = pointer) and blocksize is set to 512, the space complexity is n + N/256. that is to say, in the worst case, only N/256 of memory is wasted.

Other features of deque

Element address unchanged

Because deque does not perform data migration, an interesting feature is that the element address of deque only has push_back/push_front and remains unchanged when no insert/Erase exists.

Note that vector does not have this feature. The following code is invalid:

 

STD: vector <int> VEC;
...
Int & ELEM = VEC [I];
VEC. push_back (100 );
ELEM = 99; // error: can't access ELEM since VEC was changed!

 

Since the push_back operation exists after obtaining ELEM, the obtained element address (& ELEM) may become invalid due to memory migration. But if we change the container to STD: deque, this code will not have any problems.

 

STD: deque <int> DQ;
...
Int & ELEM = DQ [I];
DQ. push_back (100 );
ELEM = 99; // OK!

 

In addition, it should be noted that the element address remains unchanged and does not mean the iterator remains unchanged. The following code deque does not support:

 

STD: deque <int> DQ;
...
STD: deque <int >:: iterator it = DQ. Begin () + I;
DQ. push_back (100 );
* It = 99; // error: can't access iterator since deque was changed!

 

Conclusion

By comparing the time and space performances of vector, list, And deque, we can see that we recommend using the deque container as much as possible. In particular, deque is the most suitable candidate to handle massive data.

 

 

Depending on whether a container allocates memory itself is your problem, not whether it should be a vector or a queue. To avoid memory allocation problems, use vector <shared_ptr <OBJ>.

Deque cannot be memcpy

STL is just a standard but not implemented. As a vector, it should be designed as a scaled array. For example, & V [0] can be used as an array pointer (if! V. empty (), but deque does not; deque is designed to push operations at the head and tail of the ordered container at a constant time, but this design usually costs a lot, it should not be the form of a two-dimensional array you imagined. For example, the deque Design of SGI adopts a method similar to the second-level table in the file system, the direct result is that the iterator operation costs a lot. In reality, you will find that few people will use deque. Although there are few reasons in the book, it is inseparable from the high operation cost.
My opinion is that, unless it cannot, we should use vector instead of deque;
In this case, I suggest you write a container by yourself, even if you use memove, which is usually much faster than STD: vector.

Improper use of deque will cause a sharp consumption of memory!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.