std::list vs std::vector iteration
std::list vs std::vector iteration
据说遍历向量(就像读取它的所有元素一样(比遍历列表更快,因为优化了缓存。
网络上是否有任何资源可以量化它对性能的影响程度?
另外,使用自定义链表会更好吗,该列表将预先定位元素,以便它们在内存中连续?
这背后的想法是,我想以不会改变的特定顺序存储元素。我仍然需要能够在运行时快速插入一些中间,但其中大多数仍然是连续的,因为顺序不会改变。
元素连续的事实是否对缓存产生影响,或者因为我仍然会调用list_element->next
而不是++list_element
它不会改善任何东西?
向量和列表之间的主要区别在于,在向量中,元素随后在预分配的缓冲区内构造,而在列表中,元素是逐个构造的。因此,向量中的元素被授予占用连续的内存空间,而列表元素(除非某些特定情况,例如以这种方式工作的自定义分配器(不会被授予如此,并且可以在内存周围"稀疏"。
现在,由于处理器在缓存(比主RAM快1000倍(上运行,该缓存重新映射主内存的整个页面,如果元素是连续的,则它们很可能适合相同的内存页面,因此在迭代开始时一起移动到缓存中。在继续操作时,一切都发生在缓存中,而无需进一步移动数据或进一步访问较慢的 RAM。
对于 list-s,由于元素到处都是稀疏的,"转到下一个"意味着引用一个地址,该地址可能不在其前一个内存页中,因此,缓存需要在每次迭代步骤中更新,在每次迭代时访问较慢的 RAM。
性能差异在很大程度上取决于处理器以及用于主RAM和缓存的内存类型,以及std::allocator
(以及最终operator new
和malloc
(的实现方式,因此无法给出一般数字。(注意:巨大的差异意味着对缓存的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(:当您递增列表迭代器(指向的对象(时,通过在指向的对象的基础上添加一些数字来定位前向链接的位置,然后作为迭代器的新值加载。为此有多个内存访问,并且比矢量迭代操作慢。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- 使用std::函数映射对象方法
- std::list vs std::vector iteration