> if an iterator performs any better than an integer.
In general, it would be on par with array indexing.
> in the first case an indirection and a function call is involved. I don't think that all could be otpimized away.
Compilers have been optimising that all away for about two decades or so.
For proof, study the assembly listing.
> I doubt that since it is not clear where (in what function) the modification is done.
> Thus the compiler cannot [easily] assume that v.size() doesn't change.
Yes, code that is not const-correct tends to be not only more error-prone and brittle, but also less efficient.
There is no measurable difference in performance between any of these
(run the test a few times and look at the results):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include <vector>
void unknown_function( const std::vector<int>& ) ;
std::size_t count0_index_1( std::vector<int>& vec )
{
std::size_t n = 0 ;
for( std::size_t i = 0 ; i < vec.size() ; ++i )
{
unknown_function(vec) ;
if( vec[i] == 0 ) ++n ;
}
return n ;
}
std::size_t count0_index_2( std::vector<int>& vec )
{
std::size_t n = 0 ;
std::size_t sz = vec.size() ;
for( std::size_t i = 0 ; i < sz ; ++i )
{
unknown_function(vec) ;
if( vec[i] == 0 ) ++n ;
}
return n ;
}
std::size_t count0_iterator_1( std::vector<int>& vec )
{
std::size_t n = 0 ;
for( const auto& v : vec )
{
unknown_function(vec) ;
if( v == 0 ) ++n ;
}
return n ;
}
std::size_t count0_iterator_2( std::vector<int>& vec )
{
std::size_t n = 0 ;
for( auto iter = std::begin(vec) ; iter != std::end(vec) ; ++iter )
{
unknown_function(vec) ;
if( *iter == 0 ) ++n ;
}
return n ;
}
std::size_t count0_iterator_3( std::vector<int>& vec )
{
std::size_t n = 0 ;
const auto end = std::end(vec) ;
for( auto iter = std::begin(vec) ; iter != end ; ++iter )
{
unknown_function(vec) ;
if( *iter == 0 ) ++n ;
}
return n ;
}
|
http://coliru.stacked-crooked.com/a/40a3ace72979b475
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
namespace { int call_cnt = 0 ; int r = 0 ; }
void unknown_function( const std::vector<int>& ) { ++call_cnt ; }
template < typename FN > void time_it( std::vector<int>& vec, FN fn )
{
call_cnt = r = 0 ;
const auto start = std::clock() ;
r += fn(vec) ;
const auto end = std::clock() ;
std::cout << "call_cnt: " << call_cnt << " r: " << r << " milliseconds: "
<< (end-start) * 1000.0 / CLOCKS_PER_SEC << '\n' ;
}
int main()
{
const std::size_t N = 128'000'000 ;
std::vector<int> vec(N) ;
for( std::size_t i = 0 ; i < N ; ++i ) vec[i] = i%5 ;
std::size_t count0_index_1( std::vector<int>& vec ) ;
std::cout << "\ncount0_index_1\n" ;
time_it( vec, count0_index_1 ) ;
std::size_t count0_index_2( std::vector<int>& vec ) ;
std::cout << "\ncount0_index_2\n" ;
time_it( vec, count0_index_2 ) ;
std::size_t count0_iterator_1( std::vector<int>& vec ) ;
std::cout << "\ncount0_iterator_1\n" ;
time_it( vec, count0_iterator_1 ) ;
std::size_t count0_iterator_2( std::vector<int>& vec ) ;
std::cout << "\ncount0_iterator_2\n" ;
time_it( vec, count0_iterator_2 ) ;
std::size_t count0_iterator_3( std::vector<int>& vec ) ;
std::cout << "\ncount0_iterator_3\n" ;
time_it( vec, count0_iterator_3 ) ;
}
|
clang++ -O3
count0_index_1
call_cnt: 128000000 r: 25600000 milliseconds: 310.719
count0_index_2
call_cnt: 128000000 r: 25600000 milliseconds: 302.676
count0_iterator_1
call_cnt: 128000000 r: 25600000 milliseconds: 259.181
count0_iterator_2
call_cnt: 128000000 r: 25600000 milliseconds: 259.855
count0_iterator_3
call_cnt: 128000000 r: 25600000 milliseconds: 290.88 |
http://coliru.stacked-crooked.com/a/2aab35983f555a53
g++ -O3
count0_index_1
call_cnt: 128000000 r: 25600000 milliseconds: 299.913
count0_index_2
call_cnt: 128000000 r: 25600000 milliseconds: 310.956
count0_iterator_1
call_cnt: 128000000 r: 25600000 milliseconds: 299.72
count0_iterator_2
call_cnt: 128000000 r: 25600000 milliseconds: 294.523
count0_iterator_3
call_cnt: 128000000 r: 25600000 milliseconds: 263.103 |
http://coliru.stacked-crooked.com/a/ad713f2134676b12