簡體   English   中英

std :: vector或std :: list for std :: unordered_map存儲桶?

[英]std::vector or std::list for std::unordered_map buckets?

當兩個鍵映射到std::ordered_map<T>的同一存儲桶時,首選的數據結構是什么? 我不確定使用std::vector<T> (達到容量時需要復制所有元素,但需要快速迭代)還是使用容易實現的std::list<T>更好?添加新元素,但迭代速度較慢?

的std ::矢量

  • 快速遍歷元素
  • 如果由於容量不足而需要將所有元素復制到新內存中,則很糟糕

的std ::名單

  • 快速添加/刪除節點
  • 不利於迭代,因為元素不在連續內存中

即使不知道您的確切使用模式和工作量,我也會說std::vector更好。 在大多數情況下都是如此,我將在下面解釋原因。

  1. 在大多數情況下,對哈希表的查詢要比插入查詢多得多。 查找需要在存儲桶上進行迭代,而插入則需要添加元素並可能需要調整大小。 因此,針對更常見的用例進行優化更有意義。

  2. 每個插入在內部都需要進行查找,因此您至少要進行與插入一樣多的查找。 通常更多。

  3. 大多數情況下,每個存儲桶的平均密鑰數量很少。 轉化為使用較小的矢量與較小的列表。 調整小向量的大小(涉及元素的復制)將很快。

  4. 矢量“調整大小”通常不會經常發生,因此您不必非理性地害怕它。 (盡管您應該注意,當向量很小時,調整大小的確會更頻繁地發生。對於我所知道的所有實現都是如此,但糾正/規避也是不重要的。)

  5. 迭代通過矢量比迭代一個列表快得多 很多

  6. 甚至調整向量的大小和復制(或移動)向量都可以像將元素添加到列表一樣快(或幾乎一樣快)。

  7. 通過在數據類型中提供適當的“移動”支持,調整向量大小的開銷將變得更少。

  8. 您可以使用向量預先分配一定數量的元素,幾乎可以完全消除存儲桶中的所有大小調整。 例如,如果您知道99%的存儲桶將包含3個鍵或更少的鍵,則可以為每個向量保留3或4個元素,而不必重新設置大小(幾乎)。

  9. 向量(特別是當它們的元素類型較小時)比鏈表具有更高的空間效率。 一個std::list每個元素需要保留兩個額外的指針,這可能是巨大的開銷(對於8-16字節的元素,其開銷為50%-200%,具體取決於您是32位還是64位。)

  10. 由於向量的大小較小且在內存中連續,因此向量通常是更快,更好的數據結構。

  11. 最終,您必須在自己的代碼庫中以及自己的工作負載和使用模式下進行自己的度量和基准測試。 沒有完整的信息,沒有人能給您一個明確的答案。 因此,如果您的元素是非常大的,不可移動的對象,並且您主要執行插入/刪除操作以及很少的查找,那么請繼續使用鏈表。 否則,請使用向量。

您可以看一下這個基准 ,比較向量,列表和雙端隊列。 它可能會進一步幫助您決定使用向量!

暫無
暫無

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

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