• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            勤能補拙,Expter

            成都游戲Coder,記錄游戲開發(fā)過程的筆記和心得!

            一個關(guān)于容器選取的刪除問題。


            問題描述:
            1個容器有大量元素,需要進行erase大部分數(shù)據(jù)的時候,需要遍歷這些元素,然后釋放item的空間,還要erase刪除其item。

            一個庫,為了測試其性能的時候,需要保存所有外部使用者的數(shù)據(jù),這里選取了map,vector和list.

            為了簡化問題,我寫了下面測試代碼來測試各個操作:
            數(shù)據(jù)節(jié)點:

            struct node
            {
                node(
            int i){data = i;}
                
            int data;
            }

             1int _tmain(int argc, _TCHAR* argv[])
             2{
             3    typedef std::map<long,node*> Mptable;
             4    typedef std::vector<node*>   Vec;
             5    typedef std::list<node*>     List;
             6    
             7    Mptable        mapnode;
             8    Vec            vecnode;
             9    List        listnode;
            10
            11    for(int i = 1 ; i <= 100000 ; i++ )
            12    {     
            13        mapnode [ i ] = new node(i);
            14        vecnode.push_back( new node(i) );
            15        listnode.push_back( new node(i));
            16    }

            17
            18    long time = timeGetTime( );
            19    
            20    for( Mptable::iterator itr = mapnode.begin() ; itr != mapnode.end() ;  )
            21    {
            22         delete itr->second;
            23         mapnode.erase( itr++ );
            24    }

            25
            26    std::cout <<"map : spend " << timeGetTime() - time << " msec " << std::endl;
            27
            28
            29    time = timeGetTime( );
            30    
            31    for( Vec::iterator itr = vecnode.begin() ; itr != vecnode.end() ;  )
            32    {
            33         delete *itr;
            34         itr = vecnode.erase( itr );
            35    }

            36
            37    std::cout <<"vector : spend " << timeGetTime() - time << " msec " << std::endl;
            38
            39
            40    time = timeGetTime( );
            41    
            42    for( List::iterator itr = listnode.begin() ; itr != listnode.end() ;  )
            43    {
            44         delete *itr;
            45         itr = listnode.erase( itr );
            46    }

            47
            48    std::cout <<"list : spend " << timeGetTime() - time << " msec" << std::endl;
            49
            50
            51    return 0;
            52}
            Release下運行結(jié)果:
            map : spend 31 msec
            vector : spend 3734 msec
            list : spend 35 msec


            發(fā)現(xiàn)map的速度最快,vector最慢,list相當。

            其實vector就是一個Array,只是Array是靜態(tài)大小,vector可以擴展,然后查看vector的erase的源碼:
            iterator erase(const_iterator _Where)
                    
            {    // erase element at where
                    _Move(_VIPTR(_Where) + 1this->_Mylast,
                        _VIPTR(_Where));
                    _Destroy(
            this->_Mylast - 1this->_Mylast);
                    
            --this->_Mylast;
                    
            return (_Make_iter(_Where));
                    }
            有一個move操作,原來把當前iterator+1的往前移了,這樣的話會遍歷iterator后面所有的元素。


            關(guān)于map的erase原理可以查看map的實現(xiàn)源碼:
            由于map的erase后有一個維護過程,其實map是一個RB-Tree,刪除算法相對比較麻煩,刪除某個item會查找下一個item替換刪除的節(jié)點,同時還要考慮紅和黑的節(jié)點處理。同時還要保證map的erase后,平衡且有序。
            所以map的erase主要做:
            1.刪除item.
            2.讓樹平衡,且有序。

            list其實是一個雙向鏈表:
            關(guān)于刪除其實是0(1)的操作,我們查看list的erase的操作:
                iterator erase(const_iterator _Where)
                    
            {    // erase element at _Where
             #if _ITERATOR_DEBUG_LEVEL == 2
                    
            if (_Where._Getcont() != this || _Where._Ptr == this->_Myhead)
                        _DEBUG_ERROR(
            "list erase iterator outside range");
                    _Nodeptr _Pnode 
            = (_Where++)._Mynode();
                    _Orphan_ptr(
            *this, _Pnode);

             
            #else /* _ITERATOR_DEBUG_LEVEL == 2 */
                    _Nodeptr _Pnode 
            = (_Where++)._Mynode();
             
            #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

                    
            if (_Pnode != this->_Myhead)
                        
            {    // not list head, safe to erase
                        this->_Nextnode(this->_Prevnode(_Pnode)) =
                            
            this->_Nextnode(_Pnode);
                        
            this->_Prevnode(this->_Nextnode(_Pnode)) =
                            
            this->_Prevnode(_Pnode);

                        _Dest_val(
            this->_Alnod, _Pnode);
                        
            this->_Alnod.deallocate(_Pnode, 1);

                        
            --this->_Mysize;
                        }

                    
            return (_Make_iter(_Where));
                    }
            主要代碼刪除就是下面刪除部分:
            對prev和next節(jié)點進行處理即可。

            關(guān)于list的移除竟然比map還要慢.

            PS:測試為單線程。

            當為100W數(shù)據(jù)的時候:
            map : spend 300 msec
            list :   spend 385 msec

            咋list比map容器還要慢?
            還是上面的代碼不能說明問題。

            posted on 2011-01-14 14:58 expter 閱讀(2586) 評論(2)  編輯 收藏 引用 所屬分類: 其他學習筆記工作筆記算法與數(shù)據(jù)結(jié)構(gòu)

            評論

            # re: 一個關(guān)于容器選取的刪除問題。 2011-01-17 18:42 小笨象

            如果vector從最后一個開始刪除呢?
            有沒有試過?  回復  更多評論   

            # re: 一個關(guān)于容器選取的刪除問題。 2011-01-18 00:09 expter

            @小笨象
            你說那個確實可以提高效率。

            只是不解禁用優(yōu)化后,list比map快,不禁用map缺比list快。。
              回復  更多評論   

            精品国产乱码久久久久久浪潮| 国产色综合久久无码有码| 九九久久99综合一区二区| 精品久久久久香蕉网| 久久精品国产一区| 久久精品国产精品亚洲下载 | 久久er国产精品免费观看2| 91超碰碰碰碰久久久久久综合| 国产精品女同一区二区久久| 午夜精品久久影院蜜桃| 99久久免费国产特黄| 久久一区二区三区99| 91精品国产高清久久久久久io| 久久精品国产第一区二区| 久久国产高潮流白浆免费观看| 久久久99精品一区二区 | 久久综合香蕉国产蜜臀AV| 久久国产精品无码一区二区三区| 精品国产热久久久福利| 久久99精品国产麻豆宅宅| 久久精品国产精品亚洲精品| 久久91精品综合国产首页| 99国产欧美精品久久久蜜芽| 一本色综合久久| 久久久精品久久久久特色影视| 久久综合给合久久狠狠狠97色 | 精品久久久久久无码中文字幕一区| 久久夜色精品国产亚洲av| 国产精品99久久精品爆乳| 久久人人爽人人爽人人片AV不| 久久人人爽人人爽AV片| 国产精品热久久毛片| 久久久久中文字幕| 国产精品一区二区久久| 久久精品综合网| 国产2021久久精品| 日韩精品久久无码中文字幕| 国产成人久久精品二区三区| 亚洲熟妇无码另类久久久| 亚洲国产精品高清久久久| 亚洲色大成网站www久久九|