/* Performance comparison of plain vs. segmented for_each loops * over double_ended::batch_deque. * * Copyright 2017 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ #include "stdafx.h" #include #include #include #include #include std::chrono::high_resolution_clock::time_point measure_start,measure_pause; template double measure(F f) { using namespace std::chrono; static const int num_trials=10; static const milliseconds min_time_per_trial(200); std::array trials; volatile decltype(f()) res; /* to avoid optimizing f() away */ for(int i=0;i>(t2-measure_start).count()/runs; } (void)res; /* var not used warn */ std::sort(trials.begin(),trials.end()); return std::accumulate( trials.begin()+2,trials.end()-2,0.0)/(trials.size()-4); } template double measure(unsigned int n,F f) { double t=measure(f); return (t/n)*10E9; } void pause_timing() { measure_pause=std::chrono::high_resolution_clock::now(); } void resume_timing() { measure_start+=std::chrono::high_resolution_clock::now()-measure_pause; } #include #include #include #include #include #include #include #include #include bool condition( int i ) { return i % 3 == 0; } bool condition2( int i ) { return i / 2 > 0; } template void measure_for_each_contiguous() { std::cout<<"n\t" << boost::typeindex::type_id().pretty_name() << "\t" << boost::typeindex::type_id().pretty_name() << "\t\n"; for(std::size_t n=1000;n<=10000000;n*=10) { Container1 container1; container1.reserve( n ); Container2 container2; container2.reserve( n ); auto f1=[&]() { container1.clear(); for( auto i = 0; i < n; ++i ) if( condition(i) || condition2(i) ) container1.push_back( i ); return container1.size(); }; auto f2 = [&]() { container2.clear(); for( auto i = 0; i < n; ++i ) if( condition(i) || condition2(i) ) container2.unsafe_push_back( i ); return container2.size(); }; std::cout<<"10E"< void measure_for_each_deque() { std::cout << "n\t" << boost::typeindex::type_id().pretty_name() << "\t" << boost::typeindex::type_id().pretty_name() << "\t\n"; for( std::size_t n = 1000; n <= 10000000; n *= 10 ) { Container1 container1; Container2 container2; auto f1 = [&]() { container1.clear(); for( auto i = 0; i < n; ++i ) if( condition(i) || condition2(i) ) container1.push_back( i ); return container1.size(); }; auto f2 = [&]() { container2.clear(); container2.reserve_back( n ); for( auto i = 0; i < n; ++i ) if( condition(i) || condition2(i) ) container2.unsafe_push_back( i ); return container2.size(); }; std::cout << "10E" << int( std::log10( n ) ) << "\t" << measure( n, f1 ) << "\t" << measure( n, f2 ) << "\n"; } } int main() { measure_for_each_contiguous, boost::double_ended::devector>(); measure_for_each_deque, boost::double_ended::batch_deque>>(); std::cout << "\n"; }