std::vector
将其元素连续存储在内存中,而不是std::list
. 这std::vector
在迭代元素时提供了更好的性能,因为所有东西都整齐地打包,而不是在迭代std::list
.
问题是大多数时候我将智能指针存储在向量中以实现多态性或与代码的其他部分共享这些对象。由于现在每个对象都是动态分配的,我假设它们最终位于不同的内存位置。这是否违背了使用 astd::vector
并本质上将其变成类似 a 的目的std::list
?有什么办法可以解决这个问题吗?
std::vector
将其元素连续存储在内存中,而不是std::list
. 这std::vector
在迭代元素时提供了更好的性能,因为所有东西都整齐地打包,而不是在迭代std::list
.
问题是大多数时候我将智能指针存储在向量中以实现多态性或与代码的其他部分共享这些对象。由于现在每个对象都是动态分配的,我假设它们最终位于不同的内存位置。这是否违背了使用 astd::vector
并本质上将其变成类似 a 的目的std::list
?有什么办法可以解决这个问题吗?
我认为std::vector
over的最大优势std::list
是索引是 O(1) 而不是 O(n) 操作。您在谈论的是更多的二阶优化。此外,您始终可以自由地将自己的对象全部存储在一个大数组中,然后您就不会跳来跳去(如果您正在考虑缓存目的)。
不,这不是毫无意义的。
当迭代一个std::list
可能的智能指针时,您会在每个迭代器增量时跳转到内存中几乎随机的点。访问时,您再次跳转到内存中几乎随机的点。
如果您在std::vector
可能的智能指针中执行相同的迭代访问,则您只会跳转到内存中几乎随机的点一次。
你怎样才能减轻这种痛苦?
如果您使用的是 a std::shared_ptr
,请记住这样做std::make_shared
ref 计数器和数据在同一分配中,以减少缓存未命中。
如果您只是将它用于多态性,理论上您可以存储类似 a boost::variant
(或union
各种类型的 a 以及说明类型是什么的东西)之类的东西,这允许多种类型的变量存在于同一地址(一个一次,自然地)。
std::vector
std::list
与您遍历它并在每个多态对象上调用一些虚拟方法相比,它仍然具有局部性优势。
现在,由于您每次都可能调用不同的函数,因此最好按对象的实际类型对对象进行排序,以避免指令缓存未命中。