将矢量分成几个的最有效方法

时间:2014-08-27 06:58:01

标签: c++ vector c++98

我有以下代码将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());

3 个答案:

答案 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接收的向量)。避免复制元素两次更难。由于您可以使向量的元素无效,因此可以进行交换和复制。