簡體   English   中英

std :: vector :: insert vs std :: list :: operator []

[英]std::vector::insert vs std::list::operator[]

我知道std::list::operator[]沒有實現,因為它有糟糕的性能。 但是std::vector::insert它和std::list::operator[]一樣低效。 背后的解釋是什么?

std::vector::insert是因為std::vector必須滿足SequenceContainer概念的要求,而任何概念(我所知道的)都不需要operator[] ,可能會在c +中的ContiguousContainer概念中添加+17。 因此operator[]添加到可以像數組一樣使用的容器中,而insert是接口規范所必需的,因此符合某些概念的容器可以用於通用算法。

我認為斯拉瓦的答案做得最好,但我想提供一個補充說明。 通常使用數據結構,訪問比插入更常見,反之亦然。 有許多數據結構可能試圖以插入為代價來優化訪問,但反之則更為罕見,因為它在現實生活中往往不太有用。

operator[] ,如果為鏈表實現,則可能會訪問現有值(類似於它對vector )。 insert添加新值。 如果隨后的訪問非常快,那么你很可能會願意在一個vector插入一些新的元素。 在許多情況下,元素插入可以完全在關鍵路徑之外,而關鍵路徑由單個遍歷或已經存在的數據的隨機訪問組成。 因此,在這種情況下讓insert處理細節非常方便(實際上有效且正確地編寫它有點煩人)。 這實際上是一個非常罕見的矢量使用。

另一方面,在鏈表上使用operator[]幾乎總是表明您使用的是錯誤的數據結構。

std::list::operator[]需要進行O(N)遍歷,並且實際上並不符合list的設計要求。 如果需要operator[]則使用不同的容器類型。 當C ++民眾看到[]他們假定為O(1)(或者更糟糕的是,O(Log N))操作。 list提供[]會破壞它。

但是雖然std::vector::insert 也是 O(N),但它可以進行優化:通過使vector的容量以大塊增長,可以很容易地優化端點插入。 中間插入需要逐個元素移動,但在現代芯片組上也可以非常快速地執行。

[]運算符繼承自普通數組。 它一直被理解為底層容器的快速(子線性時間)訪問器。 由於list不支持子線性時間訪問,因此實現運算符沒有意義。

auto a = Container [10]; // Ideally I can assume this is quick

std::list <>::operator []的等價物是std::next <std::list<>::iterator> 記錄在cpp-reference

auto a = *std::next (Container.begin (), 10); // This may take a little while

這是容器的真正通用方式索引。 如果容器支持隨機訪問,則它將是恆定時間,否則它將是線性的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM