Здравствуйте. Такой код:
| Код | #include <algorithm> #include <iostream> #include <chrono> #include <vector>
using namespace std;
using vector_t = float;
template< class F > void measure( const char * msg, F && f ) { chrono::steady_clock::time_point start = chrono::steady_clock::now(); vector_t res = f(); chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); cout << msg << chrono::duration_cast<chrono::microseconds>(end - start).count() << "us. "; cout << "The result is " << res << endl; }
int main() { const int n = 20000000;
measure( "for sum took ", [n]() -> vector_t { vector_t sum = 0; vector< vector_t > vec( n, 1 ); for ( int i = 0; i < n; ++i ) { sum += vec[ i ]; } return sum; } ); measure( "for iters sum took ", [n]() -> vector_t { vector_t sum = 0; vector< vector_t > vec( n, 1 ); for ( auto i = vec.begin(), e = vec.end(); i != e; ++i ) { sum += *i; } return sum; } ); measure( "for_each sum took ", [n]() -> vector_t { vector_t sum = 0; vector< vector_t > vec( n, 1 ); for_each( vec.begin(), vec.end(), [&sum]( vector_t f ) { sum += f; } ); return sum; } ); measure( "accumulate sum took ", [n]() -> vector_t { vector< vector_t > vec( n, 1 ); return accumulate( vec.begin(), vec.end(), 0 ); } ); }
|
даёт такой результат:
| Цитата | for sum took 57356us. The result is 2e+007 for iters sum took 57429us. The result is 2e+007 for_each sum took 57332us. The result is 2e+007 accumulate sum took 192337us. The result is 2e+007 |
Вопрос: почему так ? ЧЯДНТ ? P.S. Компилятор MinGW 4.8.0. Параметры запуска:
| Цитата | | g++ a.cpp -std=c++11 -O2 |
P.P.S. Пробовал менять местами тесты - результат не меняется.
Добавлено через 4 минуты и 42 секунды P.P.P.S. Заглянул в исходники MinGW (файл c:\mingw\lib\gcc\i686-w64-mingw32\4.8.0\include\c++\bits\stl_numeric.h). Там реализация до противного простая
| Код | template<typename _InputIterator, typename _Tp> inline _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first) __init = __init + *__first; return __init; }
|
|