《Effective STL》讀書筆記

2021-06-27 17:30:17 字數 1087 閱讀 4497

工作之後更多地接觸到stl,在專案中stl的使用更是屢見不鮮。最近在看此書,有必要小小地總結一下。

1.用empty()而不用size()==0去判斷容器是否為空

從功能上看,兩者是一樣的。但效能上可能會有所差別。對於vector而言,size()其實就是end()-begin(), 因為它是連續記憶體分布,所以這樣計算size的時間複雜度是o(1)。但對於list這類非連續記憶體的容器來說,只能通過遍歷整個容器來獲得它的size,演算法複雜度為o(n)。而empty()則是通過在容器的開頭記錄乙個flag,只要簡單查詢這個flag的值,就知道容器是否為空。

那麼問題來了,為什麼list不能讓size()在o(1)內完成呢?其實是可以的。但是,list的底層結構是鍊錶,約定俗成的習慣是鍊錶的增刪操作是o(1)的,這樣size()就只能委屈一下了,變成了線性時間操作,每次增刪元素,我們可能在o(1)內完成,但size()就必須遍歷鍊錶了。

另外,既然知道size()不一定是輕量級的,那麼我們在寫for迴圈的時候(尤其是遍歷list),可以考慮把size_t size = list::size()這句放在迴圈體的外面,這樣我們就不用每次迭代都去計算重量級的size()了。但其實好多人還是會寫for(size_t i = 0; i < list::size(); ++i) ... 這樣的**,為什麼呢?可以少寫一行,增加可讀性麼?這種效能開銷相對於可讀性來說也太大了吧。

2.使用reserve來避免不必要的記憶體重新分配

當容器的capacity不夠了,就會申請多一倍的記憶體,然後把資料全部拷過去。申請新記憶體,拷貝,釋放舊記憶體,這三步操作是很耗時間的。所以如果我們預先能知道容器的大概capacity,就可以用reserve來預留空間,減少了記憶體不必要的reallocate。例如以下兩段**,效能差別很大。

vectorv;

for (int i = 1; i <= 1000; ++i) v.push_back(i);

vectorv;

v.reserve(1000);

for (int i = 1; i <= 1000; ++i) v.push_back(i);

好像顯得我太羅嗦了,這樣寫下去永遠都寫不完,明天再寫,簡短一點。

Effective STL 讀書筆記 1

讀技術書籍是一件開心的事情,但從來沒有哪本書像 effective 這樣讓我這麼開心。effective c 如是,more effective c 如是,effective stl 亦如是。沒有哪位作者比 scott meyers 更懂得輕鬆與嚴肅的學習了。以下只列舉被我 忽略 和 幾乎忽略 的東...

Effective STL 讀書筆記 7

item 35 使用 mi atch 或者 lexicographical compare 實現簡單的忽略大小寫的字串比較函式。int ci compare const string s1,const string s2 int ci compare impl const string s1,con...

讀書筆記之 Effective STL

條款3 使容器裡物件的拷貝操作輕量而正確 stl中採用的都是拷貝物件的方式 如果所有這些使stl的拷貝機制聽起來很瘋狂,就請重新想想。是,stl進行了大量拷貝,但它通常設計為避免不必要的物件拷貝,實際上,它也被實現為避免不必要的物件拷貝。和c和c 內建容器的行為做個對比,下面的陣列 widget w...