STL進階--vector vs deque
阿新 • • 發佈:2019-01-02
可能 cati orm real cap als 可用性 () code
vector
class Dog; // 例 1: vector<Dog> vec(6); // vec.capacity() == 6, vec.size() == 6, // 默認構造生成6 Dogs // 例 2: vector<Dog> vec; // vec.capacity() >= 0, vec.size() == 0 vec.resize(6); // vec.capacity() >= 6, vec.size() == 6, // 默認構造生成6 Dogs // 例 3: vector<Dog> vec; vec.reserve(6); // vec.capacity() >= 6, vec.size() == 0, // 不調用默認構造 // vector容量指數型增長,用完之後會重新分配,拷貝元素 /* * 避免重新分配內存的策略: * 1. 如果所需的最大元素個數已知, reserve(MAX); * 2. 如果不知道,先reserve盡可能多,等所有元素插入完畢,再將剩余的切除。 */
deque
/*
* - 沒有重新分配
* deque沒有reserve()和capacity()
* - 比vector稍慢,因為數據結構比vector復雜,因為不連續定位也有一定的開銷,更多的cache miss或page fault
* - 現代編譯器往往會把他們放到一起
*/
//固定大小線性增長
如何選擇
一般原則
- 經常需要在前面插入的? -> deque
- 性能重要的? -> vector
詳細分析
- 元素類型
- 如果不是很小的類型,那麽deque相比vector並不會低效很多
- 內存的可用性
- 大塊的連續內存分配是否可能成為問題,內存受限
數據增長是否不可預期
vector<int> vec; for (int x=0; x<1025; x++) vec.push_back(x); // 11 reallocations performed (growth ratio = 2) // workaround: reserve()
因為增長帶來的指針/引用/叠代器失效
vector<int> vec = {2,3,4,5}; int* p = &vec[3] vec.push_back(6); cout << *p << endl; // 未定義的行為 deque<int> deq = {2,3,4,5}; p = &deq[3]; deq.push_back(6); cout << *p << endl; // OK // push_front()也OK // deque: 在首尾插入不會使指針失效 // 註:在中間插入刪除的話,還是會使指針失效
vector獨有的特性: 兼容C
vector<int> vec = {2,3,4,5}; void c_fun(const int* arr, int size); c_fun(&vec[0], vec.size()); // 對於其他容器,需要先將數據拷貝到vector list<int> mylist; ... vector<int> vec(mylist.gegin(), mylist.end()); c_fun(&vec[0], vec.size()); // 註: &vector[0]可以當做C的數組使用 // 一個例外是: vector<bool> void cpp_fun(const bool* arr, int size); vector<bool> vec = {true, true, false, true}; cpp_fun(&vec[0], vec.size()); // vector<bool>的每個元素優化為由1bit來表示,可以用vecter<int>或者bitset
總結
- 經常push_front() - deque
- 高性能 - vector
- 不是細小的數據類型 - deque
- 內存受限 - deque
- 不可預期的增長 - deque
- 指針有效性 - deque
- C接口 - vector
STL進階--vector vs deque