std::list vs std::vector iteration

std::list vs std::vector iteration

本文关键字:std iteration vector list vs      更新时间:2023-10-16

据说遍历向量(就像读取它的所有元素一样(比遍历列表更快,因为优化了缓存。

网络上是否有任何资源可以量化它对性能的影响程度?

另外,使用自定义链表会更好吗,该列表将预先定位元素,以便它们在内存中连续?

这背后的想法是,我想以不会改变的特定顺序存储元素。我仍然需要能够在运行时快速插入一些中间,但其中大多数仍然是连续的,因为顺序不会改变。

元素连续的事实是否对缓存产生影响,或者因为我仍然会调用list_element->next而不是++list_element它不会改善任何东西?

向量和列表之间的主要区别在于,在向量中,元素随后在预分配的缓冲区内构造,而在列表中,元素是逐个构造的。因此,向量中的元素被授予占用连续的内存空间,而列表元素(除非某些特定情况,例如以这种方式工作的自定义分配器(不会被授予如此,并且可以在内存周围"稀疏"。

现在,由于处理器在缓存(比主RAM快1000倍(上运行,该缓存重新映射主内存的整个页面,如果元素是连续的,则它们很可能适合相同的内存页面,因此在迭代开始时一起移动到缓存中。在继续操作时,一切都发生在缓存中,而无需进一步移动数据或进一步访问较慢的 RAM。

对于 list-s,由于元素到处都是稀疏的,"转到下一个"意味着引用一个地址,该地址可能不在其前一个内存页中,因此,缓存需要在每次迭代步骤中更新,在每次迭代时访问较慢的 RAM。

性能差异在很大程度上取决于处理器以及用于主RAM和缓存的内存类型,以及std::allocator(以及最终operator newmalloc(的实现方式,因此无法给出一般数字。(注意:巨大的差异意味着对缓存的RAM不好,但也可能意味着在list-s上的实现不好(

由于数据结构的紧凑表示,缓存一致性带来的效率提升可能相当显着。在向量与列表相比的情况下,紧凑表示不仅可以更好地读取,甚至可以更好地插入(向量中移动(元素,对于某些特定体系结构,元素的量级可达 500K 个元素,如 Bjarne Stroustrup 本文的图 3 所示:

http://www2.research.att.com/~bs/Computer-Jan12.pdf

(发布者网站:http://www.computer.org/portal/web/csdl/doi/10.1109/MC.2011.353(

我认为,如果这是您的程序的关键因素,您应该在您的架构上对其进行分析。

不确定我是否可以正确解释它,但这是我的观点(我沿着下面翻译的机器指令思考:(,

向量迭代器(连续内存(:当您递增矢量迭代器时,迭代器值只需将对象的大小(在编译时已知(相加即可指向下一个对象。在大多数CPU中,这最多是一到三条指令。

列表迭代器(链表 http://www.sgi.com/tech/stl/List.html(:当您递增列表迭代器(指向的对象(时,通过在指向的对象的基础上添加一些数字来定位前向链接的位置,然后作为迭代器的新值加载。为此有多个内存访问,并且比矢量迭代操作慢。