【问题标题】:What is faster to iterate through and what is faster to create new elements on ? A vector or a Linked List ? Why? [closed]什么迭代更快,什么创建新元素更快?向量还是链表?为什么? [关闭]
【发布时间】:2022-11-25 05:57:00
【问题描述】:

我最近参加了两次工作面试,两次我都说了 vector,因为我的常识告诉我,因为访问堆上的内存比较慢。然而,链表和向量都将它们的元素存储在堆上。面试官似乎对我的回答不满意,即使我答对了。

有人可以给我这两个面试问题的教科书式答案吗?

什么可以更快地迭代,什么可以更快地创建新元素?向量还是链表?为什么?

为什么访问元素或在矢量上创建新元素更快?

【问题讨论】:

  • 容器是否分类?
  • address + 4root->next->next->next->next 哪个看起来更快?
  • “存储在堆上”不是相关部分。相关的是每个单独元素的存储位置,这将回答您的两个问题
  • 仅供参考,元素的位置无关紧要,除非它们被整理(如矢量)。从堆、堆栈或全局区域访问数据之间没有速度差异。
  • 更正。如果链表节点足够近,可以位于同一缓存行或可以放入缓存中,则可以以与向量相同的速度访问它们(同样,取决于容器的大小以及它是否可以放入缓存中)处理器的数据缓存)。

标签: c++ vector linked-list


【解决方案1】:

在大多数体系结构中,缓存局部性确保 vector 迭代速度最快,而链表在每一步都需要间接访问。向列表中插入一个新元素是 O(1) 时间。插入向量取决于您想插入的位置以及向量的内部实现方式。假设常见的 c++ 实现,在 vector 的末尾插入尽管不超过容量是 O(1),但这是一个缓慢的 (O(n)) 操作,因为重新分配意味着复制/移动。对于插入到中间,没有比手动复制/移动元素(通常是 O(n) 元素)更快的算法,这样的实现也很慢。

矢量插入性能取决于您是否可以分摊(分摊)多个插入的增长成本。在 std::vector<> 的情况下,这种增长可以很好地摊销,所以如果你进行类似批处理的处理(许多元素),那么你将体验到几乎不变的插入时间。出于实时目的,您无法在逐个调用地测量插入时间时进行摊销;那么它可能会达到 O(n) 的经验。

【讨论】:

  • 好的,改写 - 想法是,与中间有快速插入实现的列表不同,std::vector 需要求助于通用(基于移动的)算法。
  • 此外,大多数std::vector 实现在扩展时会分配额外的空间以减少追加操作时间。
  • @ThomasMatthews 是的,这就是为什么我写了“不超过容量”部分的原因。然而,当插入到一个大向量的中间时,这并没有多大帮助。
  • 我认为他们正在了解 vector 呈几何级数增长,因此 O(N) 被摊销为 O(1)
  • @NathanOliver 这对某些用例(例如批处理)有帮助,对其他用例没有帮助(例如实时处理)-但您是对的,它值得一段。
猜你喜欢
  • 1970-01-01
  • 2017-01-18
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
  • 2012-10-28
  • 2016-11-20
相关资源
最近更新 更多