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?
Of course it depends on circumstance but you can have a feeling by running some specifics. Let's see one example:
#include <iostream>
#include <vector>
uint64_t now() {
return __builtin_ia32_rdtsc();
}
template< typename T >
void erase1( std::vector<T>& vec ) {
while ( !vec.empty() ) {
vec.erase( vec.begin() );
}
}
template< typename T >
void erase2( std::vector<T>& vec ) {
while ( !vec.empty() ) {
vec.erase( vec.begin()+vec.size()-1 );
}
}
template< typename T >
void erase3( std::vector<T>& vec ) {
vec.erase( vec.begin(), vec.end() );
}
int main() {
for ( unsigned N = 1; N< (1<<20); N*=2 ) {
std::vector<int> vec;
vec.resize( N );
for ( uint32_t j=0; j<N; ++j ) vec[j] = N;
uint64_t t0 = now();
erase1( vec );
uint64_t t1 = now();
vec.resize( N );
for ( uint32_t j=0; j<N; ++j ) vec[j] = N;
uint64_t t2 = now();
erase2( vec );
uint64_t t3 = now();
vec.resize( N );
for ( uint32_t j=0; j<N; ++j ) vec[j] = N;
uint64_t t4 = now();
erase3( vec );
uint64_t t5 = now();
std::cout << (t1-t0) << " " << (t3-t2) << " " << (t5-t4) << std::endl;
}
}
erase1()
will erase one by one from the front. erase2()
will erase item by item from the back and erase3()
will erase on the entire range.
The results of this run are:
Program stdout
54 46 22
1144 66 24
230 116 22
362 74 24
596 108 24
924 128 22
2906 230 38
4622 270 24
11648 542 22
31764 960 34
94078 1876 24
313308 3874 32
1089342 7470 34
4967132 14792 34
25695930 14720 24
134255144 61492 24
585366944 122838 34
3320946224 115778 22
17386215680 484930 24
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).