我有以下代码将vectorOfInterest拆分为较小的块以发送出去。 这段代码正在运作。
但是,当我将vectorOfInterest拆分为较小的块(在subList和其余的构造函数中)时,我会复制一下。 有没有更好的使用移动而不是再次复制数据以获得更好的性能?
请注意,我无法更改OTHERCLASS :: doSend()
的参数编辑:我正在使用C ++ 98
int blockSize = 50;
vector <CLASS_T> vectorOfInterest;
// ...<populates vectorOfInterest>
do {
if(vectorOfInterest.size()> blockSize)
vector<CLASS_T>iterator from = vectorOfInterest.begin();
vector<CLASS_T>iterator to = from + blockSize;
//elements are copied again in subList and remainder
//I like to move the elements from vectorOfInterest instead.
vector<CLASS_T> subList (from, to);
vector<CLASS_T> remainder (to, vectorOfInterest.end());
vectorOfInterest.swap(remainder);
OTHERCLASS::doSend (subList); // method which sends sublists in blocks of exactly 50 to external library
}else {
//pad to exactly size 50
vectorOfInterest.resize(blockSize);
OTHERCLASS::dosend (vectorOfInterest); // method which sends sublists in blocks of exactly 50 to external library
vectorOfInterest.clear();
}
while ( !vectorOfInterest.empty());
答案 0 :(得分:7)
每次迭代都不应该从vectorOfInterest
删除元素。这涉及许多不必要的复制。相反,保持持久迭代器。您还可以避免每次迭代都分配子列表。
vector<CLASS_T>::iterator from = vectorOfInterest.begin();
vector<CLASS_T> subList;
do {
if(vectorOfInterest.end() - from > blockSize) {
subList.assign(from, from + blockSize);
from += blockSize;
OTHERCLASS::doSend(subList);
}else {
subList.assign(from, vectorOfInterest.end());
subList.resize(blockSize);
OTHERCLASS::dosend (subList);
vectorOfInterest.clear();
subList.clear();
}
} while ( !vectorOfInterest.empty());
答案 1 :(得分:3)
如果您不需要真实副本且原始向量保持不变且可访问,则可以将适当的迭代器范围boost::iterator_range<std::vector<CLASS_T>::iterator>
发送到库。对于这种方法,我假设另一个类采用行为类似于容器的模板参数。
答案 2 :(得分:3)
更重要的优化可能是在创建余数时进行的过度复制。
试试这个:
int blockSize = 50;
vector <CLASS_T> vectorOfInterest;
vector <CLASS_T> subList(blockSize);
size_t vectorSize = vectorOfInterest.size();
for(int i = 0; i < vectorSize(); i += blockSize)
{
vector<CLASS_T>iterator from = vectorOfInterest.begin() + i;
size_t thisBlockSize = min(i+blockSize, vectorSize);
vector<CLASS_T>iterator to = vectorOfInterest.begin() + thisBlockSize;
//replace this with an elementwise swap if you can
std::copy(from, to, subList.begin());
std::fill(to, vectorOfInterest.end(), /*what ever you want*/);
OTHERCLASS::doSend (subList);
}
编辑:我刚刚看到了C ++ 98部分。移动是不可能的。换句话说,您在循环中分配两个新向量,并复制每个元素两次。通过预先调整循环上方的向量,您只需分配一个向量(doSend接收的向量)。避免复制元素两次更难。由于您可以使向量的元素无效,因此可以进行交换和复制。