zoukankan      html  css  js  c++  java
  • STL进阶--vector vs deque

    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
    

    详细分析

    1. 元素类型

      • 如果不是很小的类型,那么deque相比vector并不会低效很多
    2. 内存的可用性

      • 大块的连续内存分配是否可能成为问题,内存受限
    3. 数据增长是否不可预期

        vector<int> vec;
        for (int x=0; x<1025; x++) 
           vec.push_back(x);   // 11 reallocations performed (growth ratio = 2)
      
      		//   workaround: reserve()
      
      
    4. 因为增长带来的指针/引用/迭代器失效

        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: 在首尾插入不会使指针失效
      
      // 注:在中间插入删除的话,还是会使指针失效
      
    5. 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
      

    总结

    1. 经常push_front() - deque
    2. 高性能 - vector
    3. 不是细小的数据类型 - deque
    4. 内存受限 - deque
    5. 不可预期的增长 - deque
    6. 指针有效性 - deque
    7. C接口 - vector
  • 相关阅读:
    常用模块
    python里面的奇技淫巧
    day_06、面向对象(二)
    day_06、面向对象
    day_06、递归、二分查找
    day_05、内置函数、匿名函数
    day_05、迭代器、生成器
    day_04、函数
    php调用webservice接口
    php在命令行输出进度条
  • 原文地址:https://www.cnblogs.com/logchen/p/10206069.html
Copyright © 2011-2022 走看看