我正在使用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
实际上是一个相当大的瓶颈。我真的需要加快这部分。你会建议哪种策略?
备注:
答案 0 :(得分:2)
嗯,这不是一件小事,如果你真的只需要使用(和一个)std::vector
,我认为你不能避免这种复制。
最好的解决方案是使用Persistant Data Structure。
但如果您需要存储多个版本的容器,这将非常有用。
如果您只需要以前的版本..
在我看来,这对我来说很有用的事情就是备份 元素,你会改变。您可以将std::list
(或std::vector
)与std::pair< int, myClass >
一起使用。因此,该对的first
将是元素的索引,您正在更改,second
- 备份版本。所以,最后,如果你需要恢复备份,你只需要通过这个容器并“恢复”旧数据。
删除/添加元素的情况会更复杂,但不是无法解决的。您将需要更多容器 - 一个用于已删除的元素,一个用于添加的元素,一个用于更改的元素,另一个用于更改的序列。因此,这将使您有机会执行“撤消”步骤。
嗯,这听起来更复杂,有点难以实现(因为所有可能的情况),但会提高性能(会减少副本)。
其他的事情,我想到了 - 您可以先检查容器大小。如果它很小,请制作一份完整的副本。如果它很大 - 执行“选择性备份”或其他任何调用。
请注意,这不是最佳解决方案(我猜),但只是一个想法,我现在得到了(我从来没有需要这样的东西)
希望有所帮助,甚至认为这听起来很复杂,难以实施。
答案 1 :(得分:0)
Kiril建议的替代方法是制作完整副本,但交换(或移动)在“恢复备份”阶段。
即,替换
if ( restoreBackup ) { vecA = vecB; }
带
if ( restoreBackup ) { std::swap(vecA, vecB); }
然后“恢复备份”部分基本上是免费的,您只需担心(完整)备份本身。当然,这使得任何“部分备份”策略都不可能。
听起来某种“部分”备份方案会更有效率,但提及替代方案绝不会受到伤害。 :)
答案 2 :(得分:0)
如果myClass
是POD,并且两个向量都已经是合适的大小,则可以使用memcpy:
memcpy(&dstVec[0], &srcVec[0], sizeof(myClass)*srcVec.size());
答案 3 :(得分:0)
我知道您要保留现有的std :: vector。但是这个问题听起来像是STM (Software Transactional Memory).的问题。可能值得研究。
作为替代方案,也许您可以更改修改矢量的代码,以便不会直接修改它,而是生成一个更改列表。批准更改列表后,可以将其应用于向量。
另一种方法是进行更改并构建一个撤消列表,将矢量恢复为原始形式。
所有这一切都比制作整个载体的复制要复杂得多,但是反复复制兆字节的速度会很慢而且无法解决。