快速"backup"(复制)自定义对象的大型 STL 向量

Fast way to "backup" (copy) large STL vector of custom objects

本文关键字:大型 向量 对象 STL backup 复制 快速 自定义      更新时间:2023-10-16

我使用STL向量来存储大量(~ 10^6)的自定义对象(sizeof()为其中一个对象提供了368字节)。我的程序结构要求我经常备份这个向量的副本,因为在某个步骤中所做的更改可能需要在某些条件下展开。大致看起来像

std::vector<myClass> vecA( largeNumber );
std::vector<myClass> vecB;
do
{
  vecB = vecA;
  //do lots of stuff to vecA
  if ( restoreBackup ) { vecA = vecB; }
} while (someCondition)

做一些分析,复制操作vecB = vecA实际上是一个相当大的瓶颈。我真的需要加快这部分的速度。你有什么建议?

备注:

  • 由于某些原因,我想保留STL矢量结构。
  • 我知道大多数时候只有一小部分vecA元素得到更新。所以我可以试着维护一个额外的元素列表然后只通过循环来来回复制这些元素。这是一个合适的策略吗?
  • 这个问题当然与这个问题有关,但是那里提出的解决方案并没有真正的帮助。

嗯,这不是一件微不足道的事情,我不认为你可以避免这种复制,如果你真的只需要使用(和一个)std::vector

最好的解决方案是使用持久数据结构。

但是,如果您需要存储多个版本的容器,这将非常有用。

如果你只需要以前的版本…
我想到的最简单的方法是只备份中的元素,您将更改这些元素。您可以使用std::list(或std::vector)与std::pair< int, myClass >。因此,这对的first将是元素的索引,您正在更改和second -备份版本。因此,最后,如果需要恢复备份,只需遍历这个容器并"还原"旧数据。

删除/添加元素的情况会更复杂,但不是无法解决。您必须有更多的容器——一个用于删除的元素,一个用于添加的元素,一个用于更改的元素,一个用于更改的序列。因此,这将为您提供执行"撤消"步骤的机会。

好吧,这听起来更复杂,有点难以实现(因为所有可能的情况),但会提高性能(将减少副本)。

另一件事,我想到了-你可以先检查容器的大小。如果它很小,就做一个完整的拷贝。如果它很大-执行"选择性备份"或其他什么。

注意,这不是最好的解决方案(我猜),但只是一个想法,我现在得到的(我从来没有需要过这样的东西)

希望这能有所帮助,尽管这听起来很复杂,很难实现。

Kiril建议的另一种选择是制作完整副本,但是在"恢复备份"阶段交换(或移动)。

即替换

if ( restoreBackup ) { vecA = vecB; }

if ( restoreBackup ) { std::swap(vecA, vecB); }

那么"恢复备份"部分基本上是免费的,您只需要担心(完整)备份本身。当然,这使得任何"部分备份"策略都不可能。

这听起来像是某种"部分"备份方案会更有效,但提到另一种选择也无妨。:)

如果myClass是POD,并且两个向量的大小都已经合适,则可以使用memcpy:

memcpy(&dstVec[0], &srcVec[0], sizeof(myClass)*srcVec.size());

我知道您想保留现有的std::vector。但是这个问题听起来像是为STM(软件事务性内存)制造的。这也许值得研究一下。

作为一种替代方法,也许您可以更改修改向量的代码,使其产生要进行的更改列表,而不是直接修改向量。更改列表被批准后,就可以将其应用到向量上。

另一种方法是进行更改并构建撤销列表,该列表将恢复向量的原始形式。

所有这些都比复制整个向量要复杂得多,但是反复地来回复制兆字节会很慢,没有办法。