高效的使用STL

2022-02-22 19:33:28 字數 3174 閱讀 6859

僅僅是個選擇的問題,都是stl,可能寫出來的效率相差幾倍;

熟悉以下條款,高效的使用stl;

1)stl基於拷貝的方式的來工作,任何需要放入stl中的元素,都會被複製;

這也好理解,stl工作的容器是在堆內開闢的一塊新空間,而我們自己的變數一般存放在函式棧或另一塊堆空間中;為了能夠完全控制stl自己的元素,為了能在自己的地盤隨心幹活;這就涉及到複製;

而如果複製的物件很大,由複製帶來的效能代價也不小 ;

對於大物件的操作,使用指標來代替物件能消除這方面的代價;

2)只涉及到指標拷貝操作, 沒有額外類的建構函式和賦值建構函式的呼叫;

vecttor vt1;

vt1.push_bach(mybigobj);

vecttor vt2;

vt2.push_bach(new bigobj());

注意事項:

1)容器銷毀前需要自行銷毀指標所指向的物件;否則就造成了記憶體洩漏;

2)使用排序等演算法時,需要構造基於物件的比較函式,如果使用預設的比較函式,其結果是基於指標大小的比較,而不是物件的比較;

因為對於list,size()會遍歷每乙個元素來確定大小,時間複雜度 o(n),線性時間;而empty總是保證常數時間;

使用區間成員函式有以下好處:

1)更少的函式呼叫

2)更少的元素移動

3)更少的記憶體分配

例:將v2後半部的元素賦值給v1:

單元式操作:

for (vector::const_iterator ci = v2.begin() + v2.size() / 2;

ci != v2.end();

++ci)

v1.push_back(*ci)

使用區間成員函式assign():

v1.assign(v2.begin() + v2.size() / 2, v2.end());
新增元素空間不夠時,vector會進行如下操作:

1)分配當前空間的兩倍空間;

2)將當前元素拷貝到新的空間中;

3)釋放之前的空間;

4)將新值放入新空間指定位置;

如果預先知道空間的大小,預先分配了空間避免了重新分配空間和複製的代價;

注:reserve()只是修改了容量,並非大小,向vector中增加元素還是需要通過push_back加入;

對階段性操作的定義:

先做一系列插入、完成之後,後續操作都是查詢;

在階段性的操作下,使用vector有以下優勢:

1)因為vector有序,關聯容器帶來的有序優勢散失;

2)都是使用二分法查詢的前提下,查詢演算法對連續的記憶體空間的訪問要快於離散的空間;

插入時,insert效率高;因為operator會先探查是否存在這個元素,如果不存在就構造乙個臨時的,然後才涉及到賦值,多了乙個臨時物件的構造;

更新時,[]效率更高,insert會創造乙個物件,然後覆蓋乙個原有物件;而[]是在原有的物件上直接賦值操作;

雜湊函式的預設比較函式是equal_to,因為不需要保持有序;

1)效率相比手寫更高;

stl的**都是c++專家寫出來的,專家寫出來的**在效率上很難超越;

除非我們放棄了某些特性來滿足特定的需求,可能能快過stl;比如,基於特定場合下的程式設計,放棄通用性,可移植性;

2)不容易出錯;

3)使用高層次思維程式設計

相比彙編而言,c是高階語言;一條c語言語句,用彙編寫需要好幾條;

同樣的,在stl的世界中,我們也有高層次的術語:

高層次的術語:insert/find/for_each(stl演算法)

低層次的詞彙:for /while(c++語法)

用高層次術語來思考程式設計,會更簡單;

1)基於效率考慮,成員函式知道自己這個容器和其他容器有哪些特有屬性,能夠利用到這些特性;而通用演算法不可以;

2)對於關聯容器,成員函式find基於等價搜尋;而通用演算法find基於相等來搜尋;可能導致結果不一樣;

因為內聯,在函式物件的方式中,內聯有效,而作為函式指標時,一般編譯器都不會內聯函式指標指向的函式;即使指定了inline;

比如:

inline bool doublegreater(double d1, double d2)

vectorv;

...sort(v.begin(), v.end(), doublegreater);

這個呼叫不是真的把doublegreater傳給sort,它傳了乙個doublegreater的指標。

更好的方式是使用函式物件:

sort(v.begin(), v.end(), greater())
注:《effcient c++》中的實驗結論,使用函式物件一般是裸函式的1.5倍,最多能快2倍多

需要排序前思考我們的必要需求,可能我們只是需要前多少個元素,這時並不需要使用sort這種線性時間的工具,效能消耗更少的parttition可能是更好的選擇;

以下演算法的效率從左到右依次遞減:

partition > stable_partition / nth_element / patical_sort / sort / stable_sort
功能說明:

partition :將集合分隔為滿足和不滿足某個標準兩個區間;

stable_partition :partition的穩定版本;

nth_element :獲取任意順序的前n個元素;

patical_sort :獲取前n個元素,這個n個元素已排序;

sort:排序整個區間;

stable_sort:sort的穩定版本;

為什麼vector不提供push_front()成員方法?因為效率太差,如果有太多從前面插入的需求,就不應該使用vector,而用list;

關心查詢速度,首先應該考慮雜湊容器(非標準stl容器,如:unordered_map,unordered_set);其次是排序的vector,然後是標準的關聯容器;

《effictive stl》

《efficient c++》

posted by: 大cc | 23jun,2015

部落格:blog.me115.com [訂閱]

高效的使用STL

僅僅是個選擇的問題,都是stl,可能寫出來的效率相差幾倍 熟悉以下條款,高效的使用stl 1 stl基於拷貝的方式的來工作,任何需要放入stl中的元素,都會被複製 這也好理解,stl工作的容器是在堆內開闢的一塊新空間,而我們自己的變數一般存放在函式棧或另一塊堆空間中 為了能夠完全控制stl自己的元素...

如何高效的使用STL

一些容器選用法則 1 如果程式要求隨機訪問元素,則應使用vector或deque容器 2 如果程式必須在容器的中間位置插入或刪除元素,則應採用list容器 3 如果程式不是在容器的中間位置,而是在容器首部或尾部插入或刪除元素,則應採用deque容器 4 如果只需要在讀取輸入時在容器的中間位置插入元素...

STL 什麼是STL 使用STL的好處

標準模板庫,由惠普實驗室開發的一系列的標準化的元件,目前是c 的一部分。stl的 廣義上講,分為三類 容器 迭代器 演算法,容器和演算法是通過迭代器無縫連線,string和wstring也是stl的一部分,內嵌在c 的編譯器中。特點 資料結構 容器 和演算法的分離,演算法有乙份即可,比如sort排序...