If you have defined a range of elements you want to "erase", is it more efficient to call vector::erase(iterator) for every element in the range, or to call vector::erase(iterator,iterator once?
Is erasing a range more efficient than erasing each of the elements separately?
295 views Asked by alexander.sivak AtThere are 3 answers
On
Using std::remove_if is more efficient than using a for loop with calling the method erase because for each call of the method erase all elements starting from the erasing position are moved to the left. That is the same element can be moved several times to the left.
Using the algorithm each element is moved to the left only one time.
Pay attention to that in C++ 20 there were appended two functions std::erase and std::erase_if that can be used instead of the idiom erase-remove. That is if before the C++ 20 standard you needed to write as for example
std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
v.erase( std::remove_if( std::begin( v ), std::end( v ),
[]( const auto &item )
{
return item % 2;
} ), std::end( v ) );
Then now you can just write
std::erase_if( v, []( const auto &item ) { return item % 2; } );
On
From https://en.cppreference.com/w/cpp/container/vector/erase
Complexity Linear: the number of calls to the destructor of T is the same as the number of elements erased, the assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements
It should be much more efficient to erase a range, as that allows the elements after and including the end iterator to be moved only once (but by a larger amount). Surely it's implementation specific.
Of course it depends on circumstance but you can have a feeling by running some specifics. Let's see one example:
erase1()will erase one by one from the front.erase2()will erase item by item from the back anderase3()will erase on the entire range.The results of this run are:
Results are in cycles.
You can see that erasing from the front is very costly. From the back is way faster but still apparently O(N). And erasing the range is almost instantaneous and O(1).