我迟到了回答这个问题,但是性能方面很重要,到目前为止在线答案纯粹是理论上和/或专注于内存管理方面.所以这里是我最近尝试的三个相关场景的一些实际基准信息.你的结果可能会有所不同,但至少有一些想法可以解决实际应用中的问题.
类A此处引用具有约10成员字段,其中一半是原语,而另一半的是std::string,std::vector<int>和其他动态尺寸的容器.该应用程序已经相当优化,因此我们希望看到哪个架构现在为我们提供了最快的循环A.A对象的任何成员字段的值可能会在应用程序生命周期中发生变化,但A向量中的对象数量不会在我们执行的多次重复迭代中发生变化(此连续迭代构成此应用程序执行时间的约95%).在所有情况下,循环都是使用典型的std::iterator或std::const_iterator.每个枚举A对象至少访问了几个成员字段.
场景1 - 对象指针向量
尽管最简单,但这种结构的结构std::vector<A*>比其他结构略慢.
场景2 - 对象指针向量,对象使用新的位置分配
这种方法背后的想法是我们可以通过强制将对象分配到连续的内存空间来改善缓存的局部性.因此std::vector<A*>,对象指针保证与实现连续,std::vector并且A对象本身也将在堆上连续,因为我们已经使用了放置新的习惯用法.我使用了这个答案中概述的相同方法; 有关安置新的更多信息,请点击此处.
此方案比方案1快2.7%.
场景3 - 对象矢量
我们在这里std::vector<A>直接使用.该std::vector实施保证我们的A目标将是在内存中连续的.请注意,std::vector对象确实需要考虑移动和复制构造函数A.为避免不必要的移动和/或重建,最好std::vector.reserve()提前达到最大可能需要的尺寸(如果可能),然后尽可能使用std::vector.emplace_back()(而不是push_back()).循环这个结构是最快的,因为我们能够消除一个指针间接层.
这种方法比方案1快6.4%.
对不同问题的相关答案还表明,普通对象(作为类成员)可以比相应的指针(作为类成员)快得多.
小智 1
首先,指针应该用于存储大容量的东西。因为如果你使用对象数组,会创建 n 个大的对象,并在每次存储时复制每个对象(这也是很大的成本),第二件事是如果你使用向量(STL),向量大小每次变满时都会增加的记忆。主要成本是复制第一个到第二个的数据,这实际上是主要成本,即复制。此外,此成本是内置使用时产生的最低成本。