]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/flyweight/example/perf.cpp
1 /* Boost.Flyweight example of performance comparison.
3 * Copyright 2006-2008 Joaquin M Lopez Munoz.
4 * Distributed under the Boost Software License, Version 1.0.
5 * (See accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
8 * See http://www.boost.org/libs/flyweight for library home page.
11 #include <boost/flyweight/flyweight.hpp>
12 #include <boost/flyweight/hashed_factory.hpp>
13 #include <boost/flyweight/set_factory.hpp>
14 #include <boost/flyweight/static_holder.hpp>
15 #include <boost/flyweight/simple_locking.hpp>
16 #include <boost/flyweight/refcounted.hpp>
17 #include <boost/flyweight/no_tracking.hpp>
18 #include <boost/mpl/bool.hpp>
19 #include <boost/tokenizer.hpp>
31 #if defined(BOOST_NO_STDC_NAMESPACE)
39 using namespace boost::flyweights
;
41 /* Instrumented allocator family keeping track of the memory in
45 std::size_t count_allocator_mem
=0;
51 typedef std::size_t size_type
;
52 typedef std::ptrdiff_t difference_type
;
54 typedef const T
* const_pointer
;
56 typedef const T
& const_reference
;
58 template<class U
>struct rebind
{typedef count_allocator
<U
> other
;};
61 count_allocator(const count_allocator
<T
>&){}
62 template<class U
>count_allocator(const count_allocator
<U
>&,int=0){}
64 pointer
address(reference x
)const{return &x
;}
65 const_pointer
address(const_reference x
)const{return &x
;}
67 pointer
allocate(size_type n
,const void* =0)
69 pointer p
=(T
*)(new char[n
*sizeof(T
)]);
70 count_allocator_mem
+=n
*sizeof(T
);
74 void deallocate(void* p
,size_type n
)
76 count_allocator_mem
-=n
*sizeof(T
);
80 size_type
max_size() const{return (size_type
)(-1);}
81 void construct(pointer p
,const T
& val
){new(p
)T(val
);}
82 void destroy(pointer p
){p
->~T();}
84 friend bool operator==(const count_allocator
&,const count_allocator
&)
89 friend bool operator!=(const count_allocator
&,const count_allocator
&)
96 class count_allocator
<void>
99 typedef void* pointer
;
100 typedef const void* const_pointer
;
101 typedef void value_type
;
102 template<class U
>struct rebind
{typedef count_allocator
<U
> other
;};
105 /* Define some count_allocator-based types and Boost.Flyweight components */
107 typedef std::basic_string
<
108 char,std::char_traits
<char>,count_allocator
<char>
111 typedef hashed_factory
<
112 boost::hash
<boost::mpl::_2
>,
113 std::equal_to
<boost::mpl::_2
>,
114 count_allocator
<boost::mpl::_1
>
115 > count_hashed_factory
;
118 std::less
<boost::mpl::_2
>,
119 count_allocator
<boost::mpl::_1
>
122 /* Some additional utilities used by the test routine */
129 void restart(){t
=std::clock();}
131 void time(const char* str
)
133 std::cout
<<str
<<": "<<(double)(std::clock()-t
)/CLOCKS_PER_SEC
<<" s\n";
142 boost::mpl::false_
{};
146 typename Arg1
,typename Arg2
,typename Arg3
,typename Arg4
,typename Arg5
148 struct is_flyweight
<flyweight
<T
,Arg1
,Arg2
,Arg3
,Arg4
,Arg5
> >:
153 std::size_t operator()(std::size_t n
,const count_string
& x
)const
159 /* Measure time and memory performance for a String, which is assumed
160 * to be either a plain string type or a string flyweight.
163 template<typename String
>
166 static std::size_t run(const std::string
& file
)
168 typedef std::vector
<String
,count_allocator
<String
> > count_vector
;
170 /* Define a tokenizer on std::istreambuf. */
172 typedef std::istreambuf_iterator
<char> char_iterator
;
173 typedef boost::tokenizer
<
174 boost::char_separator
<char>,
178 std::ifstream
ifs(file
.c_str());
180 std::cout
<<"can't open "<<file
<<std::endl
;
181 std::exit(EXIT_FAILURE
);
184 /* Initialization; tokenize using space and common punctuaction as
185 * separators, and keeping the separators.
190 tokenizer tok
=tokenizer(
191 char_iterator(ifs
),char_iterator(),
192 boost::char_separator
<char>(
194 "\t\n\r !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"));
196 for(tokenizer::iterator it
=tok
.begin();it
!=tok
.end();++it
){
197 txt
.push_back(String(it
->c_str()));
200 t
.time("initialization time");
207 for(int i
=0;i
<10;++i
){
208 txt2
.insert(txt2
.end(),txt
.begin(),txt
.end());
211 t
.time("assignment time");
213 /* Equality comparison */
218 for(int i
=0;i
<100;++i
){
219 c
+=std::count(txt
.begin(),txt
.end(),txt
[c
%txt
.size()]);
222 t
.time("equality comparison time");
229 for(int i
=0;i
<20;++i
){
230 s
+=std::accumulate(txt2
.begin(),txt2
.end(),s
,length_adder());
233 t
.time("value access time");
235 std::cout
<<"bytes used: "<<count_allocator_mem
;
236 if(is_flyweight
<String
>::value
){
237 std::size_t flyweight_mem
=(txt
.capacity()+txt2
.capacity())*sizeof(String
);
238 std::cout
<<"= flyweights("<<flyweight_mem
239 <<")+values("<<count_allocator_mem
-flyweight_mem
<<")";
247 /* table of test cases for the user to select from */
252 std::size_t (*test
)(const std::string
&);
255 test_case test_table
[]=
259 test
<count_string
>::run
262 "flyweight, hashed factory",
263 test
<flyweight
<count_string
,count_hashed_factory
> >::run
266 "flyweight, hashed factory, no tracking",
267 test
<flyweight
<count_string
,count_hashed_factory
,no_tracking
> >::run
270 "flyweight, set-based factory",
271 test
<flyweight
<count_string
,count_set_factory
> >::run
274 "flyweight, set-based factory, no tracking",
275 test
<flyweight
<count_string
,count_set_factory
,no_tracking
> >::run
279 const int num_test_cases
=sizeof(test_table
)/sizeof(test_case
);
284 for(int i
=0;i
<num_test_cases
;++i
){
285 std::cout
<<i
+1<<". "<<test_table
[i
].name
<<"\n";
289 std::cout
<<"select option, enter to exit: ";
291 std::getline(std::cin
,str
);
292 if(str
.empty())std::exit(EXIT_SUCCESS
);
293 std::istringstream
istr(str
);
295 if(option
>=1&&option
<=num_test_cases
){
296 --option
; /* pass from 1-based menu to 0-based test_table */
301 std::cout
<<"enter file name: ";
303 std::getline(std::cin
,file
);
304 std::size_t result
=0;
305 result
=test_table
[option
].test(file
);
307 catch(const std::exception
& e
){
308 std::cout
<<"error: "<<e
.what()<<"\n";