[英]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.