/* Measuring running insertion times of unordered associative containers * with duplicate elements. * * Copyright 2013-2022 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 #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; for(int i=0;i>(t2-measure_start).count()/runs; } std::sort(trials.begin(),trials.end()); return std::accumulate( trials.begin()+2,trials.end()-2,0.0)/(trials.size()-4); } 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 struct rand_seq { rand_seq(unsigned int n,unsigned int G):mod(n/G),gen(34862){} unsigned int operator()() { unsigned int m=dist(gen)%mod; m^=0x9e3779b9+(m<<6)+(m>>2); return m; } private: unsigned int mod; std::uniform_int_distribution dist; std::mt19937 gen; }; template void reserve(Container& s,unsigned int n) { s.rehash((unsigned int)((double)n/s.max_load_factor())); } template struct running_insertion { typedef void result_type; void operator()(unsigned int n,float Fmax,unsigned int G)const { { Container s; rand_seq rnd(n,G); s.max_load_factor(Fmax); while(n--)s.insert(rnd()); pause_timing(); } resume_timing(); } }; template struct norehash_running_insertion { typedef void result_type; void operator()(unsigned int n,float Fmax,unsigned int G)const { { Container s; rand_seq rnd(n,G); s.max_load_factor(Fmax); reserve(s,n); while(n--)s.insert(rnd()); pause_timing(); } resume_timing(); } }; template< template class Tester, typename Container1,typename Container2,typename Container3> void test( const char* title, const char* name1,const char* name2,const char* name3, float Fmax,unsigned int G) { unsigned int n0=10000,n1=3000000,dn=500; double fdn=1.05; std::cout<(),n,Fmax,G)); std::cout<(),n,Fmax,G)); std::cout<<";"<<(t/n)*10E6; t=measure(boost::bind(Tester(),n,Fmax,G)); std::cout<<";"<<(t/n)*10E6< #include #include #include #include int main() { using namespace boost::multi_index; /* some stdlibs provide the discussed but finally rejected std::identity */ using boost::multi_index::identity; typedef std::unordered_multiset container_t1; typedef boost::unordered_multiset container_t2; typedef boost::multi_index_container< unsigned int, indexed_by< hashed_non_unique > > > container_t3; test< norehash_running_insertion, container_t1, container_t2, container_t3> ( "No-rehash runnning insertion", "std::unordered_multiset", "boost::unordered_multiset", "multi_index::hashed_non_unique", 1.0,5 ); test< norehash_running_insertion, container_t1, container_t2, container_t3> ( "No-rehash runnning insertion", "std::unordered_multiset", "boost::unordered_multiset", "multi_index::hashed_non_unique", 5.0,5 ); test< running_insertion, container_t1, container_t2, container_t3> ( "Runnning insertion", "std::unordered_multiset", "boost::unordered_multiset", "multi_index::hashed_non_unique", 1.0,5 ); test< running_insertion, container_t1, container_t2, container_t3> ( "Runnning insertion", "std::unordered_multiset", "boost::unordered_multiset", "multi_index::hashed_non_unique", 5.0,5 ); }