map 效率問題

來源:互聯網
上載者:User

當關乎效率時應該在map::operator[]和map-insert之間仔細選擇

class Widget {

public:

Widget();

Widget(double weight);

Widget& operator=(double weight);

...

}

map<int, Widget> m;

m[1] = 1.50;

 

運算式m[1]是m.operator[](1)的簡化,所以這是一個map::operator[]的調用。那個函數必須返回一個Widget的

引用,因為m 的映射類型是Widget。在這裡,m裡面還沒有任何東西,所以鍵1在map裡沒有入口。因此

operator[]預設構造一個Widget來作為關聯到1的值,然後返回到那個Widget的引用。最後,Widget成為賦值目

標:被賦值的值是1.50。

換句話說,這個語句

m[1] = 1.50;

功能上等價於這個:

typedef map<int, Widget> IntWidgetMap; // 方便的

// typedef

pair<IntWidgetMap::iterator, bool> result = // 用鍵1建立新

m.insert(IntWidgetMap::value_type(1, Widget())); // 映射入口

// 和一個預設構造的

// 值對象;

// 看下面對於

// value_type的

// 注釋

result.first->second = 1.50; // 賦值給

// 新構造的

條款24:當關乎效率時應該在map::operator[]和map-insert之間仔細選擇

// 實值型別

現在已經很清楚為什麼這種方法可能降低效能了。我們先預設構造一個Widget,然後我們立即賦給它新值。

如果用想要的值構造Widget比預設構造Widget然後進行賦值顯然更高效,我們就應該用直截了當的insert調用

來替換operator[]的使用(包括它的構造加賦值):

m.insert(IntWidgetMap::value_type(1, 1.50));

這與上面的那些代碼有相同的最終效果,除了它通常節省了三次函數調用:一個建立臨時的預設構造Widget

對象,一個銷毀那個臨時的對象和一個對Widget的賦值操作。那些函數調用越昂貴,你通過使用map-insert代

替map::operator[]就能節省越多。

上面的代碼利用了每個標準容器都提供的value_type typedef。這typedef沒有什麼特別重要的,但對於map和

multimap(以及非標準容器的hash_map和hash_multimap——參見條款25),記住它是很重要的,容器元素的

類型總是某種pair。

我早先談及的operator[]被設計為簡化“添加或更新”功能,而且現在我們理解了當“增加”被執行時,insert

比operator[]更高效。當我們做更新時,情形正好相反,也就是,當一個等價的鍵(參見條款19)這已經在

map裡時。為了看出為什麼情況是這樣,看看我們的更新選項:

m[k] = v; // 使用operator[]

// 來把k的值

// 更新為v

m.insert(

IntWidgetMap::value_type(k, v)).first->second = v; // 使用insert

// 來把k的值

// 更新為v

文法本身也許會讓你信服地支援operator[],但在這裡我們關注於效率,所以我們將忽略它。insert的調用需要

IntWidgetMap::value_type類型的實參(即pair<int, Widget>),所以當我們調用insert時,我們必須構造和析構

一個那種類型的對象。那耗費了一對建構函式和解構函式,也會造成一個Widget的構造和析構,因為

pair<int, Widget>本身包含了一個Widget對象,operator[]沒有使用pair對象,所以沒有構造和析構pair和

Widget。

因此出於對效率的考慮,當給map添加一個元素時,我們斷定insert比operator[]好;而從效率和美學考慮,當

更新已經在map裡的元素值時operator[]更好。如果STL提供一個兩全其美的函數,即,在句法上迷人的包

中的高效的“添加或更新”功能。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.