/* Boost.Flyweight example of performance comparison. * * Copyright 2006-2008 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) * * See http://www.boost.org/libs/flyweight for library home page. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::clock; using ::clock_t; using ::exit; } #endif using namespace boost::flyweights; /* Instrumented allocator family keeping track of the memory in * current use. */ std::size_t count_allocator_mem=0; template class count_allocator { public: typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; templatestruct rebind{typedef count_allocator other;}; count_allocator(){} count_allocator(const count_allocator&){} templatecount_allocator(const count_allocator&,int=0){} pointer address(reference x)const{return &x;} const_pointer address(const_reference x)const{return &x;} pointer allocate(size_type n,const void* =0) { pointer p=(T*)(new char[n*sizeof(T)]); count_allocator_mem+=n*sizeof(T); return p; } void deallocate(void* p,size_type n) { count_allocator_mem-=n*sizeof(T); delete [](char *)p; } size_type max_size() const{return (size_type )(-1);} void construct(pointer p,const T& val){new(p)T(val);} void destroy(pointer p){p->~T();} friend bool operator==(const count_allocator&,const count_allocator&) { return true; } friend bool operator!=(const count_allocator&,const count_allocator&) { return false; } }; template<> class count_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; templatestruct rebind{typedef count_allocator other;}; }; /* Define some count_allocator-based types and Boost.Flyweight components */ typedef std::basic_string< char,std::char_traits,count_allocator > count_string; typedef hashed_factory< boost::hash, std::equal_to, count_allocator > count_hashed_factory; typedef set_factory< std::less, count_allocator > count_set_factory; /* Some additional utilities used by the test routine */ class timer { public: timer(){restart();} void restart(){t=std::clock();} void time(const char* str) { std::cout< struct is_flyweight: boost::mpl::false_{}; template< typename T, typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5 > struct is_flyweight >: boost::mpl::true_{}; struct length_adder { std::size_t operator()(std::size_t n,const count_string& x)const { return n+x.size(); } }; /* Measure time and memory performance for a String, which is assumed * to be either a plain string type or a string flyweight. */ template struct test { static void run(const std::string& file) { typedef std::vector > count_vector; /* Define a tokenizer on std::istreambuf. */ typedef std::istreambuf_iterator char_iterator; typedef boost::tokenizer< boost::char_separator, char_iterator > tokenizer; std::ifstream ifs(file.c_str()); if(!ifs){ std::cout<<"can't open "<( "", "\t\n\r !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")); count_vector txt; for(tokenizer::iterator it=tok.begin();it!=tok.end();++it){ txt.push_back(String(it->c_str())); } t.time("initialization time"); /* Assignment */ t.restart(); count_vector txt2; for(int i=0;i<10;++i){ txt2.insert(txt2.end(),txt.begin(),txt.end()); } t.time("assignment time"); /* Equality comparison */ t.restart(); std::size_t c=0; for(int i=0;i<100;++i){ c+=std::count(txt.begin(),txt.end(),txt[c%txt.size()]); } t.time("equality comparison time"); /* Value access */ t.restart(); std::size_t s=0; for(int i=0;i<20;++i){ s+=std::accumulate(txt2.begin(),txt2.end(),s,length_adder()); } t.time("value access time"); std::cout<<"bytes used: "<::value){ std::size_t flyweight_mem=(txt.capacity()+txt2.capacity())*sizeof(String); std::cout<<"= flyweights("<::run }, { "flyweight, hashed factory", test >::run }, { "flyweight, hashed factory, no tracking", test >::run }, { "flyweight, set-based factory", test >::run }, { "flyweight, set-based factory, no tracking", test >::run } }; const int num_test_cases=sizeof(test_table)/sizeof(test_case); int main() { try{ for(int i=0;i>option; if(option>=1&&option<=num_test_cases){ --option; /* pass from 1-based menu to 0-based test_table */ break; } } std::cout<<"enter file name: "; std::string file; std::getline(std::cin,file); test_table[option].test(file); } catch(const std::exception& e){ std::cout<<"error: "<